5

The total line number of my code is larger than the line number of the page, in minted, there is a breaklines option but it seems to breaks lines exceed the length of page line.

\documentclass[12pt]{article}

\usepackage[margin=1in]{geometry}
\usepackage{amsfonts, amsmath, amssymb}
\usepackage[none]{hyphenat}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{float}
\usepackage{url}
\usepackage[nottoc, notlot, notlof]{tocbibind}
\usepackage{url}
\usepackage{bm}
\usepackage[autostyle]{csquotes}
\usepackage[cache=false]{minted}
\usepackage{xcolor}
\usepackage{mdframed}

\definecolor{bg}{gray}{0.97}
\begin{document}

\begin{minted}[mathescape,
               linenos,
               numbersep=5pt,
               gobble=0,
               bgcolor=bg,
               frame=none,
               tabsize=4,
               breaklines=true,
               framesep=2mm]{java}
import edu.princeton.cs.algs4.Picture;


public class SeamCarver {
    private int[][] pic;
    private double[][] distTo;
    private int[][] edgeTo;
    private double[][] energy;
    private static final double DEFAULT_ENERGY_VAL = 1000.0;

    // TODO
    // create a seam carver object based on the given picture
    public SeamCarver(Picture picture) {
        if (null == picture) throw new java.lang.IllegalArgumentException("null pointer");

        energy = new double[picture.width()][picture.height()];
        pic = new int[picture.width()][picture.height()];
        // init pic
        for (int i = 0; i < picture.width(); i++) {
            for (int j = 0; j < picture.height(); j++) {
                pic[i][j] = picture.getRGB(i, j);
            }
        }
        // calculate energy
        for (int i = 0; i < picture.width(); i++) {
            for (int j = 0; j < picture.height(); j++) {
                energy[i][j] = energy(i, j);
            }
        }
    }

    // TODO
    // current picture
    public Picture picture() {
        Picture newPic = new Picture(width(), height());
        for (int i = 0; i < width(); i++) {
            for (int j = 0; j < height(); j++) {
                newPic.setRGB(i, j, pic[i][j]);
            }
        }
        return newPic;
    }

    // TODO
    // width of current picture
    public int width() {
        return pic.length;
    }

    // TODO
    // height of current picture
    public int height() {
        return pic[0].length;
    }

    // TODO
    // energy of pixel at column x and row y
    public double energy(int x, int y) {
        if ((x < 0 || x > width()-1) || (y < 0 || y > height()-1))
            throw new java.lang.IllegalArgumentException("x or y is outside its prescribed range");

        double v;
        // TODO calcuate energy
        if ((width()-1 == x || 0 == x) || (height()-1 == y) || (0 == y)) v = DEFAULT_ENERGY_VAL;
        else {
            int gradientX = calGradient(pic[x-1][y], pic[x+1][y]);
            int gradientY = calGradient(pic[x][y-1], pic[x][y+1]);
            v = Math.sqrt(gradientX+gradientY);
        }
        return v;
    }

    // TODO
    // sequence of indices for horizontal seam
    public int[] findHorizontalSeam() {
        // TODO transpose the picture
        transposePicture();
        // TODO get result
        int[] result = findVerticalSeam();
        // TODO re transpose the picture
        transposePicture();
        return result;
    }

    // TODO
    // sequence of indices for vertical seam
    public int[] findVerticalSeam() {
        distTo = new double[width()][height()];
        edgeTo = new int[width()][height()];

        for (int r = 0; r < height(); r++) {
            for (int c = 0; c < width(); c++) {
                if (0 == r) distTo[c][r] = DEFAULT_ENERGY_VAL;
                else distTo[c][r] = Double.POSITIVE_INFINITY;
            }
        }

        // Topological sort
        // TODO since the picture are sorted, loop from top row to bottom row
        for (int r = 0; r < height()-1; r++) {
            for (int c = 0; c < width(); c++)
                relaxEdge(c, r);
        }

        int[] result = new int[height()];
        double minE = Double.POSITIVE_INFINITY;
        int minIndex = -1;
        for (int i = 0; i < width(); i++) {
            if (distTo[i][height()-1] < minE) {
                minE = distTo[i][height()-1];
                minIndex = i;
            }
        }
        // get the seam
        result[height()-1] = minIndex; // init the last column
        // append the index of column values
        for (int j = height()-2; j >= 0; j--) {
            result[j] = edgeTo[result[j+1]][j+1];
        }
        // clear memory of distTo and edgeTo and the GC will automatically release memory
        distTo = null;
        edgeTo = null;
        return result;
    }

    // TODO
    // remove horizontal seam from current picture
    public void removeHorizontalSeam(int[] seam) {
        if (null == seam) throw new java.lang.IllegalArgumentException("null pointer");
        if (seam.length != width()) throw new java.lang.IllegalArgumentException("seam.length != width()");
        for (int v : seam) {
            if (v < 0 || v > height()-1) throw new java.lang.IllegalArgumentException("out of height range");
        }
        if (height() <= 1) throw new java.lang.IllegalArgumentException("height <= 1");
        // check seam value
        for (int i = 0; i < width(); i++) {
            if (i > 0 && Math.abs(seam[i]-seam[i-1]) > 1)
                throw new java.lang.IllegalArgumentException("two adjacent entries differ by more than 1");
        }
        // TODO remove horizontal seam
        transposePicture();
        removeSeam(seam);
        transposePicture();
    }

    // TODO
    // remove vertical seam from current picture
    public void removeVerticalSeam(int[] seam) {
        if (null == seam) throw new java.lang.IllegalArgumentException("null pointer");
        if (seam.length != height()) throw new java.lang.IllegalArgumentException("seam.length != height()");
        for (int v : seam) {
            if (v < 0 || v > width()-1) throw new java.lang.IllegalArgumentException("out of width range");
        }
        if (width() <= 1) throw new java.lang.IllegalArgumentException("width <= 1");
        // check seam value
        for (int i = 0; i < height(); i++) {
            if (i > 0 && Math.abs(seam[i]-seam[i-1]) > 1)
                throw new java.lang.IllegalArgumentException("two adjacent entries differ by more than 1");
        }
        // TODO remove seam
        removeSeam(seam);
    }

    private void relaxEdge(int c, int r) {
        // top-to-down
        if (distTo[c][r+1] > distTo[c][r] + energy[c][r+1]) {
            distTo[c][r+1] = distTo[c][r] + energy[c][r+1];
            edgeTo[c][r+1] = c;
        }
        // top-to-left
        if ((c-1) >= 0 && distTo[c-1][r+1] > distTo[c][r] + energy[c-1][r+1]) {
            distTo[c-1][r+1] = distTo[c][r] + energy[c-1][r+1];
            edgeTo[c-1][r+1] = c;
        }
        // top-to-right
        if ((c+1) < width() && distTo[c+1][r+1] > distTo[c][r] + energy[c+1][r+1]) {
            distTo[c+1][r+1] = distTo[c][r] + energy[c+1][r+1];
            edgeTo[c+1][r+1] = c;
        }
    }

    private void transposePicture() {
        int[][] newPic = new int[height()][width()];
        double[][] enArr = new double[height()][width()];
        for (int i = 0; i < width(); i++) {
            for (int j = 0; j < height(); j++) {
                newPic[j][i] = pic[i][j];
                enArr[j][i] = energy[i][j];
            }
        }
        energy = enArr;
        pic = newPic;
    }

    private void removeSeam(int[] seam) {
        int[][] newPic = new int[width()-1][height()];
        for (int r = 0, i = 0; r < height(); r++, i++) {
            for (int c = 0, j = 0; c < width(); c++, j++) {
                if (seam[r] == c) {
                    j--;
                    continue;
                }
                newPic[j][i] = pic[c][r];
            }
        }
        pic = newPic;

        energy = new double[width()][height()];
        for (int i = 0; i < width(); i++) {
            for (int j = 0; j < height(); j++) energy[i][j] = energy(i, j);
        }
    }

    private int calGradient(int rgb1, int rgb2) {
        int r1 = (rgb1 >> 16) & 0xFF;
        int g1 = (rgb1 >>  8) & 0xFF;
        int b1 = (rgb1 >>  0) & 0xFF;
        int r2 = (rgb2 >> 16) & 0xFF;
        int g2 = (rgb2 >>  8) & 0xFF;
        int b2 = (rgb2 >>  0) & 0xFF;
        return (r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2);
    }

    public static void main(String[] args) {
        Picture picture = new Picture("seam/6x5.png");
        SeamCarver sc = new SeamCarver(picture);
        int[] res = sc.findHorizontalSeam();
        sc.removeHorizontalSeam(res);
    }
}
\end{minted}

\end{document}

There is a similar question, but these answers can't solve my problem. Thanks!

0

1 Answer 1

7

Minted's built-in framing is quite limited. The package's documentation says that

If you want support for page breaks and advanced options, you should consider a framing package such as framed, mdframed, or tcolorbox.

Honestly I don't really know how to use mdframed, so I propose a solution with tcolorbox.

First you load tcolorbox with the minted and breakable libraries. I loaded xparse to to define a box for minted code:

\usepackage[minted,xparse,breakable]{tcolorbox}

Then you create a listings box for the minted code:

% [#1] - minted options
%  #2  - language
% [#3] - tcolorbox options
\DeclareTCBListing{mintedbox}{O{}m!O{}}{%
  listing only,% Prevent tcolorbox from trying to compile the code
  breakable,% Allow page breaks
  minted language=#2,% Make the mandatory argument be the language
  minted options={% Pass these options to minted
    linenos,
    numbersep=5pt,
    gobble=0,
    tabsize=4,
    breaklines=true,
    mathescape,
    framesep=2mm,#1},
  % Appearance tweaks
  top=0pt,% Remove borders
  bottom=0pt,
  left=0pt,
  right=0pt,
  arc=0pt,% Make the corners sharp
  colframe=bg,% Make the frame the same color as the background
  colback=bg,
  coltitle=black,% Make the title black
  #3}% And pass the options to tcolorbox

Then instead of

\begin{minted}[options]{language}

you use

\begin{mintedbox}[minted options]{language}[tcolorbox options]

And here's your MWE:

\documentclass[12pt]{article}

\usepackage[margin=1in]{geometry}
\usepackage{amsfonts, amsmath, amssymb}
\usepackage[none]{hyphenat}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{float}
\usepackage{url}
\usepackage[nottoc, notlot, notlof]{tocbibind}
\usepackage{url}
\usepackage{bm}
\usepackage[autostyle]{csquotes}
\usepackage[cache=false]{minted}
\usepackage{xcolor}
\usepackage{mdframed}

% Added this:
%{
\usepackage[minted,xparse,breakable]{tcolorbox}
\begin{document}
\definecolor{bg}{gray}{0.97}
\DeclareTCBListing{mintedbox}{O{}m!O{}}{%
  listing only,
  breakable,
  minted language=#2,
  minted options={%
    linenos,
    numbersep=5pt,
    gobble=0,
    tabsize=4,
    breaklines=true,
    mathescape,
    framesep=2mm,#1},
  % Appearance tweaks
  top=0pt,
  bottom=0pt,
  left=0pt,
  right=0pt,
  arc=0pt,
  colframe=bg,
  colback=bg,
  coltitle=black,
  #3}
%}

\begin{mintedbox}{java}[title=Title]
import edu.princeton.cs.algs4.Picture;


public class SeamCarver {
    private int[][] pic;
    private double[][] distTo;
    private int[][] edgeTo;
    private double[][] energy;
    private static final double DEFAULT_ENERGY_VAL = 1000.0;

    // TODO
    // create a seam carver object based on the given picture
    public SeamCarver(Picture picture) {
        if (null == picture) throw new java.lang.IllegalArgumentException("null pointer");

        energy = new double[picture.width()][picture.height()];
        pic = new int[picture.width()][picture.height()];
        // init pic
        for (int i = 0; i < picture.width(); i++) {
            for (int j = 0; j < picture.height(); j++) {
                pic[i][j] = picture.getRGB(i, j);
            }
        }
        // calculate energy
        for (int i = 0; i < picture.width(); i++) {
            for (int j = 0; j < picture.height(); j++) {
                energy[i][j] = energy(i, j);
            }
        }
    }

    // TODO
    // current picture
    public Picture picture() {
        Picture newPic = new Picture(width(), height());
        for (int i = 0; i < width(); i++) {
            for (int j = 0; j < height(); j++) {
                newPic.setRGB(i, j, pic[i][j]);
            }
        }
        return newPic;
    }

    // TODO
    // width of current picture
    public int width() {
        return pic.length;
    }

    // TODO
    // height of current picture
    public int height() {
        return pic[0].length;
    }

    // TODO
    // energy of pixel at column x and row y
    public double energy(int x, int y) {
        if ((x < 0 || x > width()-1) || (y < 0 || y > height()-1))
            throw new java.lang.IllegalArgumentException("x or y is outside its prescribed range");

        double v;
        // TODO calcuate energy
        if ((width()-1 == x || 0 == x) || (height()-1 == y) || (0 == y)) v = DEFAULT_ENERGY_VAL;
        else {
            int gradientX = calGradient(pic[x-1][y], pic[x+1][y]);
            int gradientY = calGradient(pic[x][y-1], pic[x][y+1]);
            v = Math.sqrt(gradientX+gradientY);
        }
        return v;
    }

    // TODO
    // sequence of indices for horizontal seam
    public int[] findHorizontalSeam() {
        // TODO transpose the picture
        transposePicture();
        // TODO get result
        int[] result = findVerticalSeam();
        // TODO re transpose the picture
        transposePicture();
        return result;
    }

    // TODO
    // sequence of indices for vertical seam
    public int[] findVerticalSeam() {
        distTo = new double[width()][height()];
        edgeTo = new int[width()][height()];

        for (int r = 0; r < height(); r++) {
            for (int c = 0; c < width(); c++) {
                if (0 == r) distTo[c][r] = DEFAULT_ENERGY_VAL;
                else distTo[c][r] = Double.POSITIVE_INFINITY;
            }
        }

        // Topological sort
        // TODO since the picture are sorted, loop from top row to bottom row
        for (int r = 0; r < height()-1; r++) {
            for (int c = 0; c < width(); c++)
                relaxEdge(c, r);
        }

        int[] result = new int[height()];
        double minE = Double.POSITIVE_INFINITY;
        int minIndex = -1;
        for (int i = 0; i < width(); i++) {
            if (distTo[i][height()-1] < minE) {
                minE = distTo[i][height()-1];
                minIndex = i;
            }
        }
        // get the seam
        result[height()-1] = minIndex; // init the last column
        // append the index of column values
        for (int j = height()-2; j >= 0; j--) {
            result[j] = edgeTo[result[j+1]][j+1];
        }
        // clear memory of distTo and edgeTo and the GC will automatically release memory
        distTo = null;
        edgeTo = null;
        return result;
    }

    // TODO
    // remove horizontal seam from current picture
    public void removeHorizontalSeam(int[] seam) {
        if (null == seam) throw new java.lang.IllegalArgumentException("null pointer");
        if (seam.length != width()) throw new java.lang.IllegalArgumentException("seam.length != width()");
        for (int v : seam) {
            if (v < 0 || v > height()-1) throw new java.lang.IllegalArgumentException("out of height range");
        }
        if (height() <= 1) throw new java.lang.IllegalArgumentException("height <= 1");
        // check seam value
        for (int i = 0; i < width(); i++) {
            if (i > 0 && Math.abs(seam[i]-seam[i-1]) > 1)
                throw new java.lang.IllegalArgumentException("two adjacent entries differ by more than 1");
        }
        // TODO remove horizontal seam
        transposePicture();
        removeSeam(seam);
        transposePicture();
    }

    // TODO
    // remove vertical seam from current picture
    public void removeVerticalSeam(int[] seam) {
        if (null == seam) throw new java.lang.IllegalArgumentException("null pointer");
        if (seam.length != height()) throw new java.lang.IllegalArgumentException("seam.length != height()");
        for (int v : seam) {
            if (v < 0 || v > width()-1) throw new java.lang.IllegalArgumentException("out of width range");
        }
        if (width() <= 1) throw new java.lang.IllegalArgumentException("width <= 1");
        // check seam value
        for (int i = 0; i < height(); i++) {
            if (i > 0 && Math.abs(seam[i]-seam[i-1]) > 1)
                throw new java.lang.IllegalArgumentException("two adjacent entries differ by more than 1");
        }
        // TODO remove seam
        removeSeam(seam);
    }

    private void relaxEdge(int c, int r) {
        // top-to-down
        if (distTo[c][r+1] > distTo[c][r] + energy[c][r+1]) {
            distTo[c][r+1] = distTo[c][r] + energy[c][r+1];
            edgeTo[c][r+1] = c;
        }
        // top-to-left
        if ((c-1) >= 0 && distTo[c-1][r+1] > distTo[c][r] + energy[c-1][r+1]) {
            distTo[c-1][r+1] = distTo[c][r] + energy[c-1][r+1];
            edgeTo[c-1][r+1] = c;
        }
        // top-to-right
        if ((c+1) < width() && distTo[c+1][r+1] > distTo[c][r] + energy[c+1][r+1]) {
            distTo[c+1][r+1] = distTo[c][r] + energy[c+1][r+1];
            edgeTo[c+1][r+1] = c;
        }
    }

    private void transposePicture() {
        int[][] newPic = new int[height()][width()];
        double[][] enArr = new double[height()][width()];
        for (int i = 0; i < width(); i++) {
            for (int j = 0; j < height(); j++) {
                newPic[j][i] = pic[i][j];
                enArr[j][i] = energy[i][j];
            }
        }
        energy = enArr;
        pic = newPic;
    }

    private void removeSeam(int[] seam) {
        int[][] newPic = new int[width()-1][height()];
        for (int r = 0, i = 0; r < height(); r++, i++) {
            for (int c = 0, j = 0; c < width(); c++, j++) {
                if (seam[r] == c) {
                    j--;
                    continue;
                }
                newPic[j][i] = pic[c][r];
            }
        }
        pic = newPic;

        energy = new double[width()][height()];
        for (int i = 0; i < width(); i++) {
            for (int j = 0; j < height(); j++) energy[i][j] = energy(i, j);
        }
    }

    private int calGradient(int rgb1, int rgb2) {
        int r1 = (rgb1 >> 16) & 0xFF;
        int g1 = (rgb1 >>  8) & 0xFF;
        int b1 = (rgb1 >>  0) & 0xFF;
        int r2 = (rgb2 >> 16) & 0xFF;
        int g2 = (rgb2 >>  8) & 0xFF;
        int b2 = (rgb2 >>  0) & 0xFF;
        return (r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2);
    }

    public static void main(String[] args) {
        Picture picture = new Picture("seam/6x5.png");
        SeamCarver sc = new SeamCarver(picture);
        int[] res = sc.findHorizontalSeam();
        sc.removeHorizontalSeam(res);
    }
}
\end{mintedbox}

\end{document}
2
  • Is the last [] optional, right? If I don't use it and the python code starts with #, I get an error: Illegal parameter number in definition of \next. #
    – Sigur
    Commented Nov 29, 2018 at 1:52
  • @Sigur Oops. Fixed it. Now it is optional :) Commented Nov 29, 2018 at 10:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .