SlideShare a Scribd company logo
1 of 44
Retos de Programación
y Estructuras de datos
de Python
Alicia
Pérez
Javier
Abadía
https://code.google.com/codejam/
convocatoria anual
varias rondas
final “en vivo”
retos más complejos
https://adventofcode.com/
25 días seguidos (1-Dic a 25-
Dic)
1 reto cada día
2 partes/reto
”tableros privados”
¿por qué?
AoC - Día 6 https://adventofcode.com/2016/day/6
AoC - Día 6
messages = """
eedadn
drvtee
eandsr
raavrd
atevrs
tsrnev
sdttsa
rasrtv
nssdts
ntnada
…
"""
 https://adventofcode.com/2016/day/6
 convertir las columnas en listas →
transponer
 contar la frecuencia de las letras
 quedarse con el máximo de cada columna
transponer filas a columnas
messages = """
eedadn
drvtee
eandsr
…
"""
messages = messages.strip().split('n');
ncolumns = len(messages[0])
assert all(len(message) == ncolumns
for message in messages)
# columns = [[]] * ncolumns # bad!!
columns = [[] for i in range(ncolumns)]
for i in range(ncolumns):
for message in messages:
columns[i].append(message[i])
zip(), iteración en paralelo
messages = """
eedadn
drvtee
eandsr
…
"""
messages = messages.strip().split('n');
ncolumns = len(messages[0])
columns = [[] for i in range(ncolumns)]
for message in messages:
for char, column in zip(message, columns):
column.append(char)
comprensiones de listas
messages = """
eedadn
drvtee
eandsr
…
"""
messages = messages.strip().split('n');
ncolumns = len(messages[0])
columns = [[] for i in range(ncolumns)]
for i, column in enumerate(columns):
column = [message[i] for message in messages]
# o también
columns = [[message[i] for message in messages]
for i in range(ncolumns)]
bum!
messages = """
eedadn
drvtee
eandsr
…
"""
messages = messages.strip().split('n');
columns = zip(*messages)
contar
# bad counting example
counts = {}
for char in column:
if not char in counts:
counts[char] = 1
else:
counts[char] += 1
sorted_counts = sorted(
counts.items(),
key=itemgetter(1)
)
most_common = sorted_counts[-1][0]
# slightly better counting example
counts = defaultdict(int)
for char in column:
counts[char] += 1
sorted_counts = sorted(
counts.items(),
key=itemgetter(1)
)
most_common = sorted_counts[-1][0]
‘most common’ → collections.Counter
>>> from collections import Counter
>>> Counter('abracadabra')
Counter({'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1})
>>> Counter('abracadabra').most_common()
[('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
combinar los más comunes
solution = ""
for column in columns:
solution += Counter(column).most_common()[0][0]
solution = ''.join(Counter(c).most_common()[0][0] for c in columns)
¿qué hemos aprendido?
 enumerate(), zip(), defaultdict()
 split(), join()
 comprensiones
 collections.Counter()
messages = messages.strip().split('n');
columns = zip(*messages)
solution = ''.join(Counter(c).most_common()[0][0] for c in columns)
print solution
AoC - Día 1 https://adventofcode.com/2016/day/1
AoC - Día 1
 https://adventofcode.com/2
016/day/1
 parsear las instrucciones
 representar las posiciones
y direcciones
 aplicar las instrucciones
 calcular la distancia
Manhattan
input = """
L2, L5, L5, R5, L2, L4, R1, R1, L4, R2, R1, …
"""
(0, 0) hacia el Norte
N
S
W E
2
5
5
(3, -5) → dist=8
parsear la entrada
input = """
L2, L5, L5, R5, L2, L4, R1, R1, L4, R2, R1, …
"""
def solve(input):
input = [s.strip() for s in input.split(',')]
direction = N
pos = Vector(0, 0)
for step in input:
instruction = Instruction(LEFT if step[0] == 'L' else RIGHT, int(step[1:]))
direction = turn(direction, instruction.side)
for _ in range(0, instruction.advance):
pos = advance(pos, directions[direction])
return pos
['L2', 'L5', 'L5', 'R5’, …]
from collections import namedtuple
Instruction = namedtuple('Instruction', "side advance")
t = Instruction(-1, 10)
t[0] == -1
t.side == -1
t[1] == 10
t.advance == 10
Vector = namedtuple('Vector', "x y")
directions = {
N: Vector(0, 1), # equiv. Vector(x=0, y=1)
E: Vector(1, 0),
S: Vector(0, -1),
W: Vector(-1, 0),
}
def advance(pos, direction):
delta = directions[direction]
return Vector(pos.x + delta.x, pos.y + delta.y)
# return Vector(*map(sum, zip(pos, delta)))
representar posiciones y direcciones
# directions
N = 0 # clockwise
E = 1
S = 2
W = 3
# sides
RIGHT = +1
LEFT = -1
def turn(direction, side):
return (direction + side) % 4
assert turn(N, RIGHT) == E
assert turn(N, LEFT) == W
assert turn(S, RIGHT) == W
assert turn(S, LEFT) == E
…
# N
# |
# W --+-- E
# |
# S
aplicar las instrucciones y calcular distancia
def solve(input):
input = [s.strip() for s in input.split(',')]
direction = N
pos = Vector(0, 0)
for step in input:
instruction = Instruction(LEFT if step[0] == 'L' else RIGHT, int(step[1:]))
direction = turn(direction, instruction.side)
for _ in range(0, instruction.advance):
pos = advance(pos, direction)
return pos
if __name__ == '__main__':
input = """ … """
pos = solve(input)
dist = abs(pos[0]) + abs(pos[1])
print "distance to (0,0) = %d" % (dist,)
complicación (2ª parte)
 si pasas dos veces por el mismo sitio, terminamos
def solve(input):
input = [s.strip() for s in input.split(',')]
direction = N
pos = Vector(0, 0)
already_visited = {pos}
for step in input:
instruction = Instruction(LEFT if step[0] == 'L' else RIGHT, int(step[1:]))
direction = turn(direction, instruction.side)
for _ in range(0, instruction.advance):
pos = advance(pos, direction)
if pos in already_visited:
return pos
already_visited.add(pos)
return pos # no se ha repetido ninguna posición
hay gente muy PRO
def solve(input):
input = [s.strip() for s in input.split(',')]
direction = 0+1j # (0,1)
pos = 0+0j # (0,0)
already_visited = {pos}
for step in input:
side, advance = step[0], int(step[1:])
direction *= 1j if side == 'L' else -1j
for _ in range(advance):
pos += direction
if pos in already_visited:
return pos
already_visited.add(pos)
return pos
if __name__ == '__main__':
input = """ … """
pos = solve(input)
dist = abs(pos.real) + abs(pos.imag)
print "distance to (0,0) = %d" % (dist,) http://mathworld.wolfram.com/Rotation.html
N
S
W E
eje real
ejeimaginario
números complejos
operaciones con números complejos
• suma: 3+5j + 2-4j = 5+1j
• rotación:
• 90º izquierda = mult por 0+1j
• 90º derecha = mult por 0-1j
(2,4) = 2+4j
¿qué hemos aprendido?
 strip(), split()
 namedtuples()
 string slicing
 números complejos
 assert como test unitarios sencillos
 set()
Code Jam
Qualification Round 2016
Prob B
https://code.google.com/codejam/contest/6254486/dashboard#s=p1
Code Jam, Qualification Round 2016, Prob B
- → + 1
-+ → ++ 1
+- → -- ++ 2
+++ → 0
--+- → +++- ---- ++++ 3
def BFS(S):
visited, queue = set(), [<initial_state>]
while queue:
depth, current = queue.pop(0)
if is_solution(current):
return depth
if current not in visited:
visited.add(current)
<add possible states to queue>
return None
optimización? BFS
def flip(S, i):
top_pankakes = ['+' if p == '-' else '-' for p in reversed(S[0:i])]
return ''.join(top_pankakes) + S[i:]
assert flip('+--+', 1) == '---+'
assert flip('+--+', 2) == '-+-+'
assert flip('+--+', 3) == '++-+'
assert flip('+--+', 4) == '-++-'
dando la vuelta a las tortitas
def shorten(S):
return ''.join(ch for ch, _ in itertools.groupby(S))
def solve(S):
visited, queue = set(), [(0, shorten(S))]
while queue:
depth, current = queue.pop(0)
if current.count('+') == len(current):
return depth
if current not in visited:
visited.add(current)
for i in range(1, len(current)+1):
flipped = shorten(flip(current, i))
if flipped not in visited:
queue.append((depth+1, flipped))
return None
implementación BFS
def minimumFlips(pancakes):
groupedHeight = 1 + pancakes.count('-+') + pancakes.count('+-')
if pancakes.endswith('-'):
return groupedHeight
else:
return groupedHeight - 1
tiene truco!
- → + 1
-+ → ++ 1
+- → -- ++ 2
+++ → 0
--+- → +++- ---- ++++ 3
AoC - Día 9 http://adventofcode.com/2016/day/9
AoC - Día 9
 https://adventofcode.com/2016/day/9
ADVENT ADVENT
A(1x5)BC ABBBBBC
(3x3)XYZ XYZXYZXYZ
(6x1)(1x3)A (1x3)A
(6x1)(1x3)A AAA
X(8x2)(3x3)ABCY X(3x3)ABC(3x3)ABCY
X(8x2)(3x3)ABCY XABCABCABCABCABCABC
Y
(27x12)(20x12)(13x14)(7x10)(1x12)A longitud 241920
(25x3)(3x3)ABC(2x3)XY(5x2)
PQRSTX(18x9)(3x2)TWO(5x7)SEVEN
longitud 445
unos casos de prueba
def do_test(lines):
for tc in lines.strip().split('n'):
compressed, expected = tc.strip().split(',')
uncompressed = uncompress(compressed)
assert uncompressed == expected, 
"bad result %s, expected %s" % (uncompressed, expected)
test_cases = """
ADVENT,ADVENT
A(1x5)BC,ABBBBBC
(3x3)XYZ,XYZXYZXYZ
…
"""
A(1x5)BC
ADVENT
X(8x2)(3x3)ABCY
def uncompress(c):
m = re.match(r'([^()]*)((d+)x(d+))(.*)', c)
if not m:
return len(c)
pre, length, reps, rest = m.groups()
length, reps = int(length), int(reps)
return len(pre) + 
uncompress(rest[:length]) * reps + 
uncompress(rest[length:])
A(1x5)BC
pre, length, reps, rest
([^()]*)((d+)x(d+))(.*)
ABBBBBC
X(8x2)(3x3)ABCY
pre, length, reps, rest
([^()]*)((d+)x(d+))(.*)
XABCABCABCABCABCABCY
regex
regex - verbose
r = re.compile(r"""
([^()]*) # pre
((d+)x(d+)) # ( length x reps )
(.*) # rest
""", re.VERBOSE)
 assert
 recursividad
 slicing
 regex
 regex + verbose
¿qué hemos aprendido?
resumen
 zip, enumerate
 tuple, set, dict
 collections
 namedtuple, Counter, defaultdict
 itertools
 groupby
 product, permutations
 slicing [:], join, split
 assert
 regex
python es MUY expresivo
tiene su propio “acento”
nunca paras de aprender
practicar, practicar, practicar
trucos
 los tipos de problemas se repiten
 librería de funciones de uso común
 vectores
 lectura de la entrada
 strip(), split()
 pensar/escribir/pintar antes de escribir código
 casos de prueba pequeños
 assert
 fuerza bruta, no suele funcionar
 pero da ideas de cómo resolverlo bien
Referencias
 Cracking the Code Interview, Gayle Laakmann McDowel
 Fluent Python, Luciano Ramalho
 Python Essential Reference, David M. Beazley
 reddit
Alicia
Pérez
Javier
Abadía
¡Gracias!
Retos de Programación en Python

More Related Content

Similar to Retos de Programación en Python

R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
Revolution Analytics
 
Please help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdfPlease help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdf
climatecontrolsv
 
Please help me fix this code! will upvote. The code needs to produce .pdf
Please help me fix this code! will upvote.  The code needs to produce .pdfPlease help me fix this code! will upvote.  The code needs to produce .pdf
Please help me fix this code! will upvote. The code needs to produce .pdf
climatecontrolsv
 
New microsoft office word document
New microsoft office word documentNew microsoft office word document
New microsoft office word document
rudrapratap61
 
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
it-people
 

Similar to Retos de Programación en Python (20)

Monadologie
MonadologieMonadologie
Monadologie
 
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
R + Hadoop = Big Data Analytics. How Revolution Analytics' RHadoop Project Al...
 
Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
Please help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdfPlease help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdf
 
RHadoop の紹介
RHadoop の紹介RHadoop の紹介
RHadoop の紹介
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
Please help me fix this code! will upvote. The code needs to produce .pdf
Please help me fix this code! will upvote.  The code needs to produce .pdfPlease help me fix this code! will upvote.  The code needs to produce .pdf
Please help me fix this code! will upvote. The code needs to produce .pdf
 
Brief tour of psp-std
Brief tour of psp-stdBrief tour of psp-std
Brief tour of psp-std
 
Python 101 language features and functional programming
Python 101 language features and functional programmingPython 101 language features and functional programming
Python 101 language features and functional programming
 
New microsoft office word document
New microsoft office word documentNew microsoft office word document
New microsoft office word document
 
Jan 2012 HUG: RHadoop
Jan 2012 HUG: RHadoopJan 2012 HUG: RHadoop
Jan 2012 HUG: RHadoop
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Python Tidbits
Python TidbitsPython Tidbits
Python Tidbits
 
Swift rocks! #1
Swift rocks! #1Swift rocks! #1
Swift rocks! #1
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...The Functional Programming Triad of Folding, Scanning and Iteration - a first...
The Functional Programming Triad of Folding, Scanning and Iteration - a first...
 
Visualization team presentation
Visualization team presentation Visualization team presentation
Visualization team presentation
 
Introduction to Functional Programming with Scala
Introduction to Functional Programming with ScalaIntroduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
 
Programming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAYProgramming in lua STRING AND ARRAY
Programming in lua STRING AND ARRAY
 
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
«Python на острие бритвы: PyPy project» Александр Кошкин, Positive Technologies
 

More from Javier Abadía

More from Javier Abadía (12)

Python Asíncrono - Async Python
Python Asíncrono - Async PythonPython Asíncrono - Async Python
Python Asíncrono - Async Python
 
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - ExasolExtendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
Extendiendo Django: Cómo Escribir Tu Propio Backend de Base de Datos - Exasol
 
UX/UI para Desarrolladores
UX/UI para DesarrolladoresUX/UI para Desarrolladores
UX/UI para Desarrolladores
 
Reactividad en Angular, React y VueJS
Reactividad en Angular, React y VueJSReactividad en Angular, React y VueJS
Reactividad en Angular, React y VueJS
 
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDOLas reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
Las reglas que hay que romper para que tu equipo de desarrollo sea el más RÁPIDO
 
Django + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar DjangoDjango + Vue, JavaScript de 3ª generación para modernizar Django
Django + Vue, JavaScript de 3ª generación para modernizar Django
 
Vue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMRVue.js + Django - configuración para desarrollo con webpack y HMR
Vue.js + Django - configuración para desarrollo con webpack y HMR
 
Anatomía de un Bot para Resultados Electorales
Anatomía de un Bot para Resultados ElectoralesAnatomía de un Bot para Resultados Electorales
Anatomía de un Bot para Resultados Electorales
 
Deep learning image classification aplicado al mundo de la moda
Deep learning image classification aplicado al mundo de la modaDeep learning image classification aplicado al mundo de la moda
Deep learning image classification aplicado al mundo de la moda
 
Análisis de colores: cómo analizar tendencias de moda automáticamente
 Análisis de colores: cómo analizar tendencias de moda automáticamente Análisis de colores: cómo analizar tendencias de moda automáticamente
Análisis de colores: cómo analizar tendencias de moda automáticamente
 
Codemotion 2016 - d3.js un taller divertido y difícil
Codemotion 2016 - d3.js un taller divertido y difícilCodemotion 2016 - d3.js un taller divertido y difícil
Codemotion 2016 - d3.js un taller divertido y difícil
 
La Noche Electoral
La Noche ElectoralLa Noche Electoral
La Noche Electoral
 

Recently uploaded

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc
 

Recently uploaded (20)

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
TEST BANK For Principles of Anatomy and Physiology, 16th Edition by Gerard J....
 
Design Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptxDesign Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptx
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
Decarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational PerformanceDecarbonising Commercial Real Estate: The Role of Operational Performance
Decarbonising Commercial Real Estate: The Role of Operational Performance
 
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...Stronger Together: Developing an Organizational Strategy for Accessible Desig...
Stronger Together: Developing an Organizational Strategy for Accessible Desig...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 
Choreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software EngineeringChoreo: Empowering the Future of Enterprise Software Engineering
Choreo: Empowering the Future of Enterprise Software Engineering
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 

Retos de Programación en Python

  • 1. Retos de Programación y Estructuras de datos de Python Alicia Pérez Javier Abadía
  • 2. https://code.google.com/codejam/ convocatoria anual varias rondas final “en vivo” retos más complejos https://adventofcode.com/ 25 días seguidos (1-Dic a 25- Dic) 1 reto cada día 2 partes/reto ”tableros privados”
  • 4. AoC - Día 6 https://adventofcode.com/2016/day/6
  • 5. AoC - Día 6 messages = """ eedadn drvtee eandsr raavrd atevrs tsrnev sdttsa rasrtv nssdts ntnada … """  https://adventofcode.com/2016/day/6  convertir las columnas en listas → transponer  contar la frecuencia de las letras  quedarse con el máximo de cada columna
  • 6. transponer filas a columnas messages = """ eedadn drvtee eandsr … """ messages = messages.strip().split('n'); ncolumns = len(messages[0]) assert all(len(message) == ncolumns for message in messages) # columns = [[]] * ncolumns # bad!! columns = [[] for i in range(ncolumns)] for i in range(ncolumns): for message in messages: columns[i].append(message[i])
  • 7. zip(), iteración en paralelo messages = """ eedadn drvtee eandsr … """ messages = messages.strip().split('n'); ncolumns = len(messages[0]) columns = [[] for i in range(ncolumns)] for message in messages: for char, column in zip(message, columns): column.append(char)
  • 8. comprensiones de listas messages = """ eedadn drvtee eandsr … """ messages = messages.strip().split('n'); ncolumns = len(messages[0]) columns = [[] for i in range(ncolumns)] for i, column in enumerate(columns): column = [message[i] for message in messages] # o también columns = [[message[i] for message in messages] for i in range(ncolumns)]
  • 9. bum! messages = """ eedadn drvtee eandsr … """ messages = messages.strip().split('n'); columns = zip(*messages)
  • 10.
  • 11. contar # bad counting example counts = {} for char in column: if not char in counts: counts[char] = 1 else: counts[char] += 1 sorted_counts = sorted( counts.items(), key=itemgetter(1) ) most_common = sorted_counts[-1][0] # slightly better counting example counts = defaultdict(int) for char in column: counts[char] += 1 sorted_counts = sorted( counts.items(), key=itemgetter(1) ) most_common = sorted_counts[-1][0]
  • 12.
  • 13. ‘most common’ → collections.Counter >>> from collections import Counter >>> Counter('abracadabra') Counter({'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) >>> Counter('abracadabra').most_common() [('a', 5), ('r', 2), ('b', 2), ('c', 1), ('d', 1)]
  • 14. combinar los más comunes solution = "" for column in columns: solution += Counter(column).most_common()[0][0] solution = ''.join(Counter(c).most_common()[0][0] for c in columns)
  • 15. ¿qué hemos aprendido?  enumerate(), zip(), defaultdict()  split(), join()  comprensiones  collections.Counter() messages = messages.strip().split('n'); columns = zip(*messages) solution = ''.join(Counter(c).most_common()[0][0] for c in columns) print solution
  • 16. AoC - Día 1 https://adventofcode.com/2016/day/1
  • 17. AoC - Día 1  https://adventofcode.com/2 016/day/1  parsear las instrucciones  representar las posiciones y direcciones  aplicar las instrucciones  calcular la distancia Manhattan input = """ L2, L5, L5, R5, L2, L4, R1, R1, L4, R2, R1, … """ (0, 0) hacia el Norte N S W E 2 5 5 (3, -5) → dist=8
  • 18. parsear la entrada input = """ L2, L5, L5, R5, L2, L4, R1, R1, L4, R2, R1, … """ def solve(input): input = [s.strip() for s in input.split(',')] direction = N pos = Vector(0, 0) for step in input: instruction = Instruction(LEFT if step[0] == 'L' else RIGHT, int(step[1:])) direction = turn(direction, instruction.side) for _ in range(0, instruction.advance): pos = advance(pos, directions[direction]) return pos ['L2', 'L5', 'L5', 'R5’, …] from collections import namedtuple Instruction = namedtuple('Instruction', "side advance") t = Instruction(-1, 10) t[0] == -1 t.side == -1 t[1] == 10 t.advance == 10
  • 19. Vector = namedtuple('Vector', "x y") directions = { N: Vector(0, 1), # equiv. Vector(x=0, y=1) E: Vector(1, 0), S: Vector(0, -1), W: Vector(-1, 0), } def advance(pos, direction): delta = directions[direction] return Vector(pos.x + delta.x, pos.y + delta.y) # return Vector(*map(sum, zip(pos, delta))) representar posiciones y direcciones # directions N = 0 # clockwise E = 1 S = 2 W = 3 # sides RIGHT = +1 LEFT = -1 def turn(direction, side): return (direction + side) % 4 assert turn(N, RIGHT) == E assert turn(N, LEFT) == W assert turn(S, RIGHT) == W assert turn(S, LEFT) == E … # N # | # W --+-- E # | # S
  • 20.
  • 21. aplicar las instrucciones y calcular distancia def solve(input): input = [s.strip() for s in input.split(',')] direction = N pos = Vector(0, 0) for step in input: instruction = Instruction(LEFT if step[0] == 'L' else RIGHT, int(step[1:])) direction = turn(direction, instruction.side) for _ in range(0, instruction.advance): pos = advance(pos, direction) return pos if __name__ == '__main__': input = """ … """ pos = solve(input) dist = abs(pos[0]) + abs(pos[1]) print "distance to (0,0) = %d" % (dist,)
  • 22. complicación (2ª parte)  si pasas dos veces por el mismo sitio, terminamos def solve(input): input = [s.strip() for s in input.split(',')] direction = N pos = Vector(0, 0) already_visited = {pos} for step in input: instruction = Instruction(LEFT if step[0] == 'L' else RIGHT, int(step[1:])) direction = turn(direction, instruction.side) for _ in range(0, instruction.advance): pos = advance(pos, direction) if pos in already_visited: return pos already_visited.add(pos) return pos # no se ha repetido ninguna posición
  • 23. hay gente muy PRO def solve(input): input = [s.strip() for s in input.split(',')] direction = 0+1j # (0,1) pos = 0+0j # (0,0) already_visited = {pos} for step in input: side, advance = step[0], int(step[1:]) direction *= 1j if side == 'L' else -1j for _ in range(advance): pos += direction if pos in already_visited: return pos already_visited.add(pos) return pos if __name__ == '__main__': input = """ … """ pos = solve(input) dist = abs(pos.real) + abs(pos.imag) print "distance to (0,0) = %d" % (dist,) http://mathworld.wolfram.com/Rotation.html N S W E eje real ejeimaginario números complejos operaciones con números complejos • suma: 3+5j + 2-4j = 5+1j • rotación: • 90º izquierda = mult por 0+1j • 90º derecha = mult por 0-1j (2,4) = 2+4j
  • 24.
  • 25. ¿qué hemos aprendido?  strip(), split()  namedtuples()  string slicing  números complejos  assert como test unitarios sencillos  set()
  • 26. Code Jam Qualification Round 2016 Prob B https://code.google.com/codejam/contest/6254486/dashboard#s=p1
  • 27. Code Jam, Qualification Round 2016, Prob B - → + 1 -+ → ++ 1 +- → -- ++ 2 +++ → 0 --+- → +++- ---- ++++ 3
  • 28. def BFS(S): visited, queue = set(), [<initial_state>] while queue: depth, current = queue.pop(0) if is_solution(current): return depth if current not in visited: visited.add(current) <add possible states to queue> return None optimización? BFS
  • 29. def flip(S, i): top_pankakes = ['+' if p == '-' else '-' for p in reversed(S[0:i])] return ''.join(top_pankakes) + S[i:] assert flip('+--+', 1) == '---+' assert flip('+--+', 2) == '-+-+' assert flip('+--+', 3) == '++-+' assert flip('+--+', 4) == '-++-' dando la vuelta a las tortitas
  • 30. def shorten(S): return ''.join(ch for ch, _ in itertools.groupby(S)) def solve(S): visited, queue = set(), [(0, shorten(S))] while queue: depth, current = queue.pop(0) if current.count('+') == len(current): return depth if current not in visited: visited.add(current) for i in range(1, len(current)+1): flipped = shorten(flip(current, i)) if flipped not in visited: queue.append((depth+1, flipped)) return None implementación BFS
  • 31. def minimumFlips(pancakes): groupedHeight = 1 + pancakes.count('-+') + pancakes.count('+-') if pancakes.endswith('-'): return groupedHeight else: return groupedHeight - 1 tiene truco! - → + 1 -+ → ++ 1 +- → -- ++ 2 +++ → 0 --+- → +++- ---- ++++ 3
  • 32.
  • 33. AoC - Día 9 http://adventofcode.com/2016/day/9
  • 34. AoC - Día 9  https://adventofcode.com/2016/day/9 ADVENT ADVENT A(1x5)BC ABBBBBC (3x3)XYZ XYZXYZXYZ (6x1)(1x3)A (1x3)A (6x1)(1x3)A AAA X(8x2)(3x3)ABCY X(3x3)ABC(3x3)ABCY X(8x2)(3x3)ABCY XABCABCABCABCABCABC Y (27x12)(20x12)(13x14)(7x10)(1x12)A longitud 241920 (25x3)(3x3)ABC(2x3)XY(5x2) PQRSTX(18x9)(3x2)TWO(5x7)SEVEN longitud 445
  • 35. unos casos de prueba def do_test(lines): for tc in lines.strip().split('n'): compressed, expected = tc.strip().split(',') uncompressed = uncompress(compressed) assert uncompressed == expected, "bad result %s, expected %s" % (uncompressed, expected) test_cases = """ ADVENT,ADVENT A(1x5)BC,ABBBBBC (3x3)XYZ,XYZXYZXYZ … """
  • 36. A(1x5)BC ADVENT X(8x2)(3x3)ABCY def uncompress(c): m = re.match(r'([^()]*)((d+)x(d+))(.*)', c) if not m: return len(c) pre, length, reps, rest = m.groups() length, reps = int(length), int(reps) return len(pre) + uncompress(rest[:length]) * reps + uncompress(rest[length:]) A(1x5)BC pre, length, reps, rest ([^()]*)((d+)x(d+))(.*) ABBBBBC X(8x2)(3x3)ABCY pre, length, reps, rest ([^()]*)((d+)x(d+))(.*) XABCABCABCABCABCABCY regex
  • 37. regex - verbose r = re.compile(r""" ([^()]*) # pre ((d+)x(d+)) # ( length x reps ) (.*) # rest """, re.VERBOSE)
  • 38.
  • 39.  assert  recursividad  slicing  regex  regex + verbose ¿qué hemos aprendido?
  • 40. resumen  zip, enumerate  tuple, set, dict  collections  namedtuple, Counter, defaultdict  itertools  groupby  product, permutations  slicing [:], join, split  assert  regex python es MUY expresivo tiene su propio “acento” nunca paras de aprender practicar, practicar, practicar
  • 41. trucos  los tipos de problemas se repiten  librería de funciones de uso común  vectores  lectura de la entrada  strip(), split()  pensar/escribir/pintar antes de escribir código  casos de prueba pequeños  assert  fuerza bruta, no suele funcionar  pero da ideas de cómo resolverlo bien
  • 42. Referencias  Cracking the Code Interview, Gayle Laakmann McDowel  Fluent Python, Luciano Ramalho  Python Essential Reference, David M. Beazley  reddit

Editor's Notes

  1. Advent of Code 25 días seguidos 1 reto cada día 2 partes/reto Code Jam de Google convocatoria anual varias rondas más complejos https://code.google.com/codejam/
  2. karate kid practicar descubrir nuevas herramientas entrevistas de programación