The CTO's Session
Gonzalo Ruiz de Villa Suárez
CTO @ GFT
GoPro
General Fusion
SnapChat
Tesla Motors
Square
SpaceX
Touch Bionics
Carbon3D
¿Qué tienen en común?
Software
"It is easier for software to enter other industries that for other industries to hire software people."
Benedict Evans
"For decades, BigCo tried to industrialize software. Wrong! It turns out, the future is to softwareize industry."
Reginald Braithwaite
PWA
Instant Apps
Rendimiento en la plataforma
Capacidades en el mercado
Nuevas tecnologías
Big Data
Es tan... 2013
Serverless Architectures
↓ costes de operación
↓ costes de desarrollo
↓ costes de escalación
↑ simplicidad de operaciones
↑ más ecológico
vendor control
multitenancy
vendor lock-in
cuestiones de seguridad
"auto" DoS
gestión de estado, testing, tiempo de ejecución
...
Problemas de regresión: lineales, logísticas y poisson
Análisis de clusters: K-means, detección de anomalías
Sistemas de recomendación
SVM
Redes neuronales
....
APIs, APIs, APIs...
Quantum Computing
Algoritmo de Grover
Algoritmo de Shor
Programación con conceptos contraintuitivos
Por ejemplo:
- No localidad
- Superposición de estados con números complejos
De momento solo podemos programar con 5 qbits y unas 40 operaciones
Evolucionar lo existente
Apostar por un producto
Empezar de cero
Compartir y documentar el proceso de decisión
¿Es tan importante la decisión?
¿O son nuestras acciones posteriores la que la hacen difícil de deshacer?
Conoce a tu equipo
Entrena a tu equipo
Codewars
Codefights
HackerRank
...
Competiciones de programación
♘ vs ♝
/**
* Determines the victor in a contest between Knight and Bishop.
* @param {Array} Position of the Knight (e.g., [4, 'C'] for C4)
* @param {Array} Position of the Bishop (e.g., [5, 'A'] for A5)
* @returns {String} The winning piece -- 'None' if there are no victors
*/
function knightVsBishop(knightPosition, bishopPosition) {
var board = new ChessBoard(),
knight = board.addPiece(Knight),
bishop = board.addPiece(Bishop),
bishopWins,
knightWins;
knight.setPosition(knightPosition);
bishop.setPosition(bishopPosition);
if (knight.isAbleToTakePiece(bishop)) {
return 'Knight';
}
if (bishop.isAbleToTakePiece(knight)) {
return 'Bishop';
}
return 'None';
}
/**
* A container for chess pieces.
* Traditional chess board, so this has support for x-axis of A through H
* and a y-axis from 1 to 8.
* @constructor
*/
function ChessBoard() {
this.xMap = {
'a': 1,
'b': 2,
'c': 3,
'd': 4,
'e': 5,
'f': 6,
'g': 7,
'h': 8
};
this.y = [1, 2, 3, 4, 5, 6, 7, 8];
this.pieces = [];
}
/**
* Generates a chess piece of the requested type.
* @param {prototype} The prototype of the requested chess piece. Should extend ChessPiece.
* @returns {Object} Chess piece of requested type.
*/
ChessBoard.prototype.addPiece = function(type) {
var piece = Object.create(type.prototype);
piece.setContainer(this);
this.pieces.push(piece);
return piece;
};
/**
* Generates an extent for the chess board.
* @returns {Array} Extent for the chess board (e.g., [[0, 0],[8, 8]]).
*/
ChessBoard.prototype.getExtent = function() {
var extent = [[1, 1],[this.y[0], this.y[this.y.length - 1]]];
for (var key in this.xMap) {
key = key.toLowerCase();
if (this.xMap[key] < extent[0][0]) {
extent[0][0] = this.xMap[key];
}
if (this.xMap[key] > extent[0][1]) {
extent[0][1] = this.xMap[key];
}
}
return extent;
};
/**
* Converts a provided position (e.g., [4, 'C']) into a set of x,y coordinates.
* @param {Array} A position.
* @returns {Array} x and y coordinates corresponding to the provided position.
*/
ChessBoard.prototype.positionToCoords = function(position) {
return [this.xMap[position[1].toLowerCase()], position[0]];
};
/**
* Base type from which other chess pieces type should inherit.
* @constructor
*/
function ChessPiece() {
}
/**
* Hook for containers to provide a reference to themselves
* when adding chess pieces.
* @param {Object} A container object; e.g., ChessBoard.
*/
ChessPiece.prototype.setContainer = function(container) {
this.container = container;
};
/**
* Sets the position of this chess piece.
* @param {Array} The position (e.g., [4, 'C'] for 4C).
*/
ChessPiece.prototype.setPosition = function(position) {
this.position = position;
this.coords = this.container.positionToCoords(position);
};
/**
* Determines whether or not a requested move is possible
* within the extent of this piece's container.
* @param {Array} The requested move, as a set of coordinates (e.g., [4, 5]).
* @returns {Boolean} True if the move is possible, false otherwise.
*/
ChessPiece.prototype.isMovePossible = function(coordinate) {
var extent = this.container.getExtent();
for (var i = 0; i < coordinate.length; i++) {
for (var j = 0; j < extent.length; j++) {
if ((coordinate[i] < extent[j][0]) || (coordinate[i] > extent[j][1])) {
return false;
}
}
}
return true;
};
/**
* Returns an array of possible moves within this piece's container.
* Should be overridden by individual chess piece implementations (e.g., Knight).
* @returns {Array} An array of possible moves, as coordinates.
*/
ChessPiece.prototype.getPossibleMoves = function() {
return [];
};
/**
* Determines whether or not this piece can take the requested piece.
* @param {ChessPiece} The requested piece.
* @returns {Boolean} True if this piece can take the requested piece, false otherwise.
*/
ChessPiece.prototype.isAbleToTakePiece = function(piece) {
var possibleMoves = this.getPossibleMoves(),
possibleMove;
for (var i = 0; i < possibleMoves.length; i++) {
possibleMove = possibleMoves[i];
if ((possibleMove[0] === piece.coords[0]) && (possibleMove[1] === piece.coords[1])) {
return true;
}
}
return false;
};
/**
* Chess piece representing the Knight type.
* Can move in a pattern of two along one axis, followed by one along the other axis.
* Example:
* 4
* 3 1 2
* 2
* 1 0
* +ABCDEFGH
*/
function Knight() {
}
Knight.prototype = Object.create(ChessPiece.prototype);
/**
* Returns an array of possible moves within this piece's container.
* @returns {Array} An array of possible moves, as coordinates.
*/
Knight.prototype.getPossibleMoves = function() {
var coords = this.coords,
moves = [],
self = this;
[[coords[0] + 1, coords[1] + 2],
[coords[0] + 2, coords[1] + 1],
[coords[0] - 1, coords[1] - 2],
[coords[0] - 2, coords[1] - 1],
[coords[0] - 1, coords[1] + 2],
[coords[0] + 1, coords[1] - 2],
[coords[0] - 2, coords[1] + 1],
[coords[0] + 2, coords[1] - 1]].forEach(function(possibleMove) {
if (self.isMovePossible(possibleMove)) {
moves.push(possibleMove);
}
});
return moves;
};
/**
* Chess piece representing the Bishop type.
* Can move in a diagonal line to any edge of the container.
* Example:
* 8
* 7
* 6 5
* 5 4
* 4 3
* 3 2
* 2 1
* 1 0
* +ABCDEFGH
*/
function Bishop() {
}
Bishop.prototype = Object.create(ChessPiece.prototype);
/**
* Returns an array of possible moves within this piece's container.
* @returns {Array} An array of possible moves, as coordinates.
*/
Bishop.prototype.getPossibleMoves = function() {
var extent = this.container.getExtent(),
coords = this.coords,
moves = [],
self = this,
inProgress = true,
previous = coords;
[function() {
previous = [previous[0] - 1, previous[1] - 1];
return self.isMovePossible(previous);
}, function() {
previous = [previous[0] - 1, previous[1] + 1];
return self.isMovePossible(previous);
}, function() {
previous = [previous[0] + 1, previous[1] - 1];
return self.isMovePossible(previous);
}, function() {
previous = [previous[0] + 1, previous[1] + 1];
return self.isMovePossible(previous);
}].forEach(function(isMovePossible) {
previous = coords,
inProgress = true;
while (inProgress) {
if (isMovePossible()) {
moves.push(previous);
} else {
inProgress = false;
}
}
});
return moves;
};
function knightVsBishop(knightPosition, bishopPosition) {
let knightHit = getKnightHitLine(knightPosition);
let bishopHit = getBishopHitLine(bishopPosition);
knightPosition = knightPosition.join('');
bishopPosition = bishopPosition.join('');
if (knightHit.indexOf(bishopPosition) != -1) {
return 'Knight';
} else if (bishopHit.indexOf(knightPosition) != -1) {
return 'Bishop';
} else {
return 'None';
}
}
let getKnightHitLine = ([num, char]) => {
let hitLine = [];
let charCode = char.charCodeAt(0);
if (
num - 2 >= boardAxisY.firstNumber &&
charCode - 1 >= boardAxisX.firstCharCode
) {
let str = (num - 2) + String.fromCharCode(charCode - 1);
hitLine.push(str);
}
if (
num - 1 >= boardAxisY.firstNumber &&
charCode - 2 >= boardAxisX.firstCharCode
) {
let str = (num - 1) + String.fromCharCode(charCode - 2);
hitLine.push(str);
}
if (
num - 2 >= boardAxisY.firstNumber &&
charCode + 1 <= boardAxisX.lastCharCode
) {
let str = (num - 2) + String.fromCharCode(charCode + 1);
hitLine.push(str);
}
if (
num - 1 >= boardAxisY.firstNumber &&
charCode + 2 <= boardAxisX.lastCharCode
) {
let str = (num - 1) + String.fromCharCode(charCode + 2);
hitLine.push(str);
}
if (
num + 2 <= boardAxisY.lastNumber &&
charCode + 1 <= boardAxisX.lastCharCode
) {
let str = (num + 2) + String.fromCharCode(charCode + 1);
hitLine.push(str);
}
if (
num + 1 <= boardAxisY.lastNumber &&
charCode + 2 <= boardAxisX.lastCharCode
) {
let str = (num + 1) + String.fromCharCode(charCode + 2);
hitLine.push(str);
}
if (
num + 2 <= boardAxisY.lastNumber &&
charCode - 1 >= boardAxisX.firstCharCode
) {
let str = (num + 2) + String.fromCharCode(charCode - 1);
hitLine.push(str);
}
if (
num + 1 <= boardAxisY.lastNumber &&
charCode - 2 >= boardAxisX.firstCharCode
) {
let str = (num + 1) + String.fromCharCode(charCode - 2);
hitLine.push(str);
}
return hitLine;
};
let getBishopHitLine = ([num, char]) => {
let hitLine = [];
let charCode = char.charCodeAt(0);
let figurePosition = num + char;
for (
let i = num, c = charCode;
i >= boardAxisY.firstNumber && c >= boardAxisX.firstCharCode;
i--, c--
) {
// to left bottom corner
let str = i + String.fromCharCode(c);
if (str !== figurePosition) {
hitLine.push(str);
}
}
for (
let i = num, c = charCode;
i >= boardAxisY.firstNumber && c <= boardAxisX.lastCharCode;
i--, c++
) {
// to right bottom corner
let str = i + String.fromCharCode(c);
if (str !== figurePosition) {
hitLine.push(str);
}
}
for (
let i = num, c = charCode;
i <= boardAxisY.lastNumber && c <= boardAxisX.lastCharCode;
i++, c++
) {
// to left top corner
let str = i + String.fromCharCode(c);
if (str !== figurePosition) {
hitLine.push(str);
}
}
for (
let i = num, c = charCode;
i <= boardAxisY.lastNumber && c >= boardAxisX.firstCharCode;
i++, c--
) {
// to right top corner
let str = i + String.fromCharCode(c);
if (str !== figurePosition) {
hitLine.push(str);
}
}
return hitLine;
};
const boardAxisY = {
firstNumber: 1,
lastNumber: 8
};
const boardAxisX = {
firstCharCode: 65, // letter A
lastCharCode: 72 // letter H
};
function knightVsBishop(knightPosition, bishopPosition) {
// Three possible outputs are "Knight", "Bishop", and "None";
var kp = getPos(knightPosition);
var bp = getPos(bishopPosition);
var ret;
ret = knight(kp[0], kp[1], bp[0], bp[1]);
if(ret)
return 'Knight';
ret = bishop(bp[0], bp[1], kp[0], kp[1]);
if(ret)
return 'Bishop';
return 'None';
}
function bishop(x, y, dx, dy) {
return Math.abs(x - dx) == Math.abs(y - dy);
}
function knight(x, y, dx, dy) {
if(x - 2 == dx && y + 1 == dy)
return true;
if(x - 1 == dx && y + 2 == dy)
return true;
if(x + 1 == dx && y + 2 == dy)
return true;
if(x + 2 == dx && y + 1 == dy)
return true;
if(x + 2 == dx && y - 1 == dy)
return true;
if(x + 1 == dx && y - 2 == dy)
return true;
if(x - 1 == dx && y - 2 == dy)
return true
if(x - 2 == dx && y - 1 == dy)
return true
return false;
}
function getPos(p) {
var alpha = 'ABCDEFGH';
var nums = '87654321';
return [nums.indexOf(p[0]), alpha.indexOf(p[1])];
}
const knightVsBishop =
([nx,ny], [bx,by], diffX, diffY) => (
diffX = Math.abs(nx-bx),
diffY = Math.abs(ny.charCodeAt(0)-by.charCodeAt(0)),
diffX == diffY ? "Bishop" :
diffX && diffY && (diffX + diffY) == 3 ? "Knight"
: "None"
)
¿Sugerencias para entrenar enfoques de alto nivel?
Al final no se trata de ser el primero en tener una idea, sino de implementarla mejor.
Atraer, cuidar y nutrir talento es lo importante.
La tecnología es coyuntural.
¡Gracias!
Créditos de fotos e imágenes:
- The Matrix Movie
- Machine Learning Course Logo by Coursera
- Amigos: kingofwallpapers.com/friend.html
- Bob Sponge Imagination: @athumanperson picsart.com
- Bebe sabio: gifak.net
- Las fieras combatientes: awegif.com
- Pendulo de Foucault: Wikimedia Commons
- Huerto: elhuertodellopez.blogspot.com
- Hombre sobre cuerda floja: Designed by Freepik
- Tortitas deliciosas: micocinitadejuguete.blogspot.com.es
- Mujer Zen: Designed by Jcomp / Freepik
- Don Draper en llamas: don-draper-is-zen.tumblr.com
The CTO's Session
By Gonzalo Ruiz de Villa
The CTO's Session
- 3,139