@Override
    public Vector solve(Basis b) {

        BigInteger[][] big = convertToBigInteger(b);

        LLL.integral_LLL(big, big.length, big[0].length);

        // TODO: Not actually necessary to do this conversion,
        // because we have to convert to double for solving linear equations
        int[][] reduced = convertToInteger(big);
        
        double shortest = Double.MAX_VALUE;
        int vectorIndex = -1;
        for(int i = 0; i < b.vecCount; i++) {
            double vLen = Vector.vectorLength(reduced[i]);
            //System.out.println(String.format("%s", vLen));
            // Find the shortest vector and solve a system of linear equations
            // to reconstruct it
            if(vLen < shortest){
                shortest = vLen;
                vectorIndex = i;
            }
        }
        
        // Need to swap dimensions here:
        // The LinearSolve library expects vectors in columns (not rows)
        // and the matrix must be square
        // (the rest are sufficiently large, but linearly independent so they
        // won't prevent solving the system of linear equations)
        int sysSize = Math.max(b.dim, b.vecCount);
        double[][] A = new double[sysSize][sysSize];
        for(int i = 0; i < sysSize; i++){
            for(int j = 0; j < sysSize; j++){
                A[i][j] = 10000000 + i + j;
            }
        }
        
        for(int v = 0; v < b.vecCount; v++) {
            for(int d = 0; d < b.dim; d++) {
                A[d][v] = b.vectors[v][d]; // NOTE: dimension swap
            }
        }
        
        // coefficients to solve for (1 per basis vector)
        double[] coefs = new double[sysSize];
        
        // Copy coordinate values from the shortest vector (target) 
        double[] sVecVals = new double[b.dim];
        for(int i = 0; i < b.dim; i++){
            sVecVals[i] = reduced[vectorIndex][i];
        }
        
        LinearSolve linearSolver = new LinearSolve(A);
        linearSolver.solve(coefs, sVecVals);
        
        // Construct the vector with these coefficients
        Vector v = b.zeroVector();
        for(int i = 0; i < b.vecCount; i++){
            v.coef[i] = (int)Math.round(coefs[i]);
        }

        updateIfBest(v);
        return v;
    }