[Tex/LaTex] How to put a figure to the right of a multiple-choice question

exampositioning

I have code to automatically align the four choices of a multiple choice question and put the answer after the question with dotted lines. It works quite well with the exam document class (see the screenshot of the output below).

image shot

The minimal sample code is below:

\documentclass[answers,a4paper]{exam}
\usepackage{graphicx}
\usepackage{environ}
\usepackage[normalem]{ulem}
\usepackage{etoolbox}
\usepackage{enumitem}
%
\renewcommand{\choiceshook}{%
    \setlength{\leftmargin}{10pt}%
}

\newlength\answerspace
\setlength\answerspace{0.5in}
\newcommand\dottedanswerline[1][{}]{%
  % One optional argument, the default value of which is empty.
  \unskip\linebreak[0]\enspace
  \hbox{}\nobreak\dotfill 
  \ifprintanswers
    \hbox to \answerspace{(\hfil#1\hfil)}%
  \else
    \hbox{(\hskip 0.5in)}%
  \fi
}% dottedanswerline

\makeatletter
\newlength\choiceitemwidth
\newif\ifshowsolution \showsolutiontrue
\newcounter{choiceitem}%

\def\thechoiceitem{\Alph{choiceitem}}%
\setlength{\fboxsep}{0pt}
%\def\makechoicelabel#1{#1\uline{\thechoiceitem.}\else\thechoiceitem.\fi\space} %underline the answer item label if we want to print the answer
\def\makechoicelabel#1{#1\fbox{\thechoiceitem.}\else\thechoiceitem.\fi\space} %underline the answer item label if we want to print the answer

\def\choice@mesureitem#1{\cr\stepcounter{choiceitem}\makechoicelabel#1}%

%measure the choices, this is the first time we need to parse the \BODY
\def\choicemesureitem{\@ifstar
  {\choice@mesureitem\ifprintanswers \xappto\theanswer{\thechoiceitem}\ignorespaces}%
  {\choice@mesureitem\iffalse}}%

\def\choice@blockitem#1{%
  \ifnum\value{choiceitem}>0\hfill\fi
  \egroup\hskip0pt
  \hbox to \choiceitemwidth\bgroup\hss\refstepcounter{choiceitem}\makechoicelabel#1}

\def\choiceblockitem{\@ifstar
  {\choice@blockitem\ifprintanswers\ignorespaces}%
  {\choice@blockitem\iffalse}}

\def\choice@paraitem#1{%
  \par\refstepcounter{choiceitem}\makechoicelabel#1}

\def\choiceparaitem{\@ifstar
  {\choice@paraitem\ifprintanswers\ignorespaces}%
  {\choice@paraitem\iffalse}}


\NewEnviron{items}{%
  \def\theanswer{}
  \begingroup
    \let\item\choicemesureitem
    \setcounter{choiceitem}{0}%
    \settowidth{\global\choiceitemwidth}{\vbox{\halign{##\hfil\cr\BODY\crcr}}}%
  \endgroup \dottedanswerline[\theanswer]
  \setlist[trivlist]{nosep}
  \trivlist\item\relax%  
  \parindent0pt%
  \setcounter{choiceitem}{0}%
  \ifdim\choiceitemwidth<0.25\columnwidth
    \choiceitemwidth=0.25\columnwidth
    \let\item\choiceblockitem
    \bgroup\BODY\hfill\egroup
  \else\ifdim\choiceitemwidth<0.5\columnwidth
    \choiceitemwidth=0.5\columnwidth
    \let\item\choiceblockitem
    \bgroup\BODY\hfill\egroup
  \else % \choiceitemwidth > 0.5\columnwidth
    \let\item\choiceparaitem
    \BODY
  \fi\fi
  \endtrivlist
}
\makeatother


\begin{document}

\section{multiply choice questions}
\begin{questions}

\question this is a question
\begin{items}
\item wrong choice
\item wrong choice
\item wrong choice
\item * right choice
\end{items}

\question this is a question
\begin{items}
\includegraphics[width=5cm,height=5cm]{example-image}\\
\item wrong choice
\item wrong choice
\item wrong choice
\item * right choice
\end{items}

\question this is a question
\begin{items}
\includegraphics[width=5cm,height=5cm]{example-image}\\
\item wrong choice
\item wrong choice wrong choice wrong choice wrong choice
\item * right choice
\item wrong choice

\end{items}

\end{questions}

\end{document}

You see I have put a figure in the question. However, I want to save space, which means I want to put the figure in the right side of the choices (as the the red arrows show). How can this be done?

Note that the four choices were typeset in a compact way, which means they can either be put in one row, or two rows, or four rows, depending on their max length of the choice. Details can be found in the solved question here: automatically align the four choices of a multiple choice question and put the answer after the question with dotted lines.

EDIT: In my TeX code, the image width is used to calculate the maximum length of the choices, so, if I use the following code:

\question this is a question
\begin{items}
\includegraphics[width=15cm,height=5cm]{example-image}\\
\item wrong choice
\item wrong choice
\item wrong choice
\item * right choice
\end{items}

Note that the image has width of 15cm, now the result choices were typeset in one column, but it is expected in two columns, see the second question of the screen shot.

EDIT2: I have an issue with nickie's solution, if I have such code:

\question this is a question
\begin{items}[{\includegraphics[width=15cm,height=2cm]{example-image}}]
\item wrong choice
\item wrong choice
\item wrong choice
\item * right choice
\end{items}

I will get the image here:

image is too wide, so the choices does not look good

So, in this case(I guess the image is larger then 0.75\columnwidth), we should put all the four choices below the figure.

Best Answer

Here's what I came up with. I changed your items environment, which now takes an optional parameter: whatever has to be right aligned with the answers.

\usepackage[export]{adjustbox}
\newdimen\qanswd
\newdimen\qanswdtmp
\newbox\qimgbox
\NewEnviron{items}[1][]{%
  \def\theanswer{}
  \begingroup
    \let\item\choicemesureitem
    \setcounter{choiceitem}{0}%
    \settowidth{\global\choiceitemwidth}{\vbox{\halign{##\hfil\cr\BODY\crcr}}}%
  \endgroup \dottedanswerline[\theanswer]
  \setbox\qimgbox\hbox{#1}%
  \setlist[trivlist]{nosep}
  \trivlist\item\relax%
  \qanswd=\linewidth%
  \advance\qanswd-\wd\qimgbox%
  % handle large images (leaving less than 30% space)
  \qanswdtmp=0.3\linewidth%
  \ifnum\qanswd<\qanswdtmp%
    %\strut\hfill% uncomment to right-align large images
    \unhbox\qimgbox%
    %\hfill\strut% uncomment this too to center them
    \par%
    \qanswd=\linewidth%
    \setbox\qimgbox\hbox{}%
  \fi%
  % end of handling for large images
  \begin{minipage}[t]{\qanswd}
  \trivlist\item\relax%
  \parindent0pt%
  \setcounter{choiceitem}{0}%
  \ifdim\choiceitemwidth<0.25\columnwidth
    \choiceitemwidth=0.25\columnwidth
    \let\item\choiceblockitem
    \bgroup\BODY\hfill\egroup
  \else\ifdim\choiceitemwidth<0.5\columnwidth
    \choiceitemwidth=0.5\columnwidth
    \let\item\choiceblockitem
    \bgroup\BODY\hfill\egroup
  \else % \choiceitemwidth > 0.5\columnwidth
    \let\item\choiceparaitem
    \BODY
  \fi\fi
  \endtrivlist
  \end{minipage}%
  \adjustbox{valign=t}{\unhbox\qimgbox}
  \endtrivlist
}

You have to use it like this:

\question this is a question
\begin{items}[{\includegraphics[width=5cm,height=5cm]{example-image}}]
\item wrong choice
\item wrong choice
\item wrong choice
\item * right choice
\end{items}

Notice the extra braces around your \includegraphics, which protect the nested brackets.

I'm getting an underfull \hbox but it was there to begin with.

result