TeX Alchemist Online

TeX を使って化学のお仕事をしています。

TeX で乱数を使う (4) ~ 2次元シャッフル

前々回の記事 TeX で乱数を使う (2) では,「インプットした問題ストックからランダムな順序で出題する」というお題を扱いました。前回の記事 TeX で乱数を使う (3) では,「語順整序問題における語順をランダムに並べ替え,逆置換を用いてその正解も自動表示する」というお題を扱いました。今回は,その2つを合体して,「語順がランダムに並べ替えられた語順整序問題を,ランダムな順序で出題する」という複合版を実現してみましょう。

これはすなわち,「問題の順序」と「各問題における語順」という2方向のシャッフルが絡み合うことになります。

f:id:doraTeX:20190118130045p:plain
2方向のシャッフルの共存

2方向のシャッフルが同時に共存するので,名前空間の分離を意識するなど,しっかり設計しておかないと双方のシャッフルが干渉してしまいます。randomshuffle パッケージの name オプションに問題番号を含めることで,「シャッフルのシャッフル」が干渉せぬよう実現できます。randomshuffle パッケージ自体も,2方向のシャッフルの共存にしっかり耐えるよう改修しておきました。

【コード例】

例によってセンター試験「英語」の語順整序問題を3年分ストックし,それをランダムな順序で,語順もランダムにシャッフルして出題し,それに応じた正解を提示する LaTeX ソースを作ってみました。

%#!uplatex
\documentclass[uplatex]{jsarticle}
\usepackage{randomshuffle}
\makeatletter
\newcount\problemnum
\newcount\problemcount
\newcount\wordnum
\newcount\wordcount

\long\def\addProblem#1{%
  \advance\problemcount\@ne
  \@namedef{problem\the\problemcount}{#1}%
}

% 選択肢の記号を ㋐, ㋑, …… で出力する
\def\MaruKata#1{\chardef\@labelchar=\expandafter\ucs\numexpr13007+#1\relax\textsf{\@labelchar}}

%% 語群のインプットと空欄出力
\def\語順整序#1{%
  \wordnum=\z@
  \@tfor\word:=#1\do{%
    \advance\wordnum\@ne
    \edef\thisword{word\the\problemnum-\the\wordnum}%
    \expandafter\@namedef\expandafter{\expandafter\thisword\expandafter}\expandafter{\word}%%% 単語を登録
    \space\framebox[1cm][c]{\texttt{\the\wordnum}}\space%%% 空欄出力
  }%
  \randomshuffle[name=shuffledword\the\problemnum]{1}{\wordnum}%% 語群をランダムシャッフルし,\@nameuse{shuffledword問題番号}{単語番号} からアクセス
  \expandafter\global\expandafter\newcount\csname wordcount\the\problemnum\endcsname%% この問題の単語数を保存するカウンタ
  \expandafter\global\csname wordcount\the\problemnum\endcsname=\wordnum%% この問題の単語数を保存
}

%% シャッフルされた語群を出力
\def\語群出力{%
  \par\noindent\textgt{《語群》}\par\nopagebreak
  \wordnum=\z@
  {\loop
    \advance\wordnum\@ne
    \def\thisword{\@nameuse{word\the\problemnum-\@nameuse{shuffledword\the\problemnum}{\the\wordnum}}}% シャッフルされた選択肢の内容
    \makebox[\dimexpr\linewidth/\wordcount\relax][l]{\MaruKata{\wordnum}\kern1zw\relax\thisword}% 選択肢を出力
  \ifnum\wordcount>\wordnum\repeat}%
}

%% 逆置換を用いて正解を出力
\def\解答出力{%
  \par\noindent\textgt{【解答】}\par\nopagebreak
  {\loop
    \advance\wordnum\@ne
    \def\answernum{\@nameuse{shuffledword\the\problemnum inverse}{\the\wordnum}}% 正解選択肢の番号(\@nameuse{shuffledword問題番号inverse}{単語番号} でアクセス)
    \texttt{\the\wordnum:} \MaruKata{\answernum}% 正解の記号を出力
    \qquad
  \ifnum\wordcount>\wordnum\repeat}%
}

\def\printProblem#1{%
  \@nameuse{problem\shuffled{#1}}%%% 問題文出力
  \wordcount=\@nameuse{wordcount\the\problemnum}%% この問題の単語数を取得
  \語群出力
  \解答出力
  \par
  \vspace{\baselineskip}%
}

\def\printAllProblems{%
  \problemnum=\z@
  {\loop
    \advance\problemnum\@ne
    \noindent\textsf{\the\problemnum}\par\nopagebreak
    \printProblem{\the\problemnum}%
  \ifnum\problemnum<\problemcount\repeat}%
}

\makeatother

\addProblem{% 2018センター英語
  Student: What are we going to do with the Australian students after they drive?\par
  Teacher: The first night, we'll have a barbecue by the river so that you all \語順整序{{can}{get}{to}{know}{each}{other}} quickly.
}
\addProblem{% 2018センター英語
  Bridget: How was your basketball season last year?\par
  Toshi: I \語順整序{{was}{the second}{highest}{scorer}{on}{the team}}.
}
\addProblem{% 2018センター英語
  Evan: I want to buy my first computer, but I don't know which one I should get.\par
  Sam: Don't worry. Electronic stores always have experts available to give advice \語順整序{{to}{those}{who}{aren't}{familiar}{with}} using computer.
}
\addProblem{% 2017センター英語
  Keita: You have so many things in your room.\par
  Cindy: I know. Actually, \語順整序{{I}{find}{it}{difficult}{to}{keep}} it neat and clean.
}
\addProblem{% 2017センター英語
  Ted: Professor Jones suggested that I rewrite this essay.\par
  Jack: Oh, well, \語順整序{{it}{may}{cost}{you}{a few}{hours}} but I'm sure you'll get a higher grade on it.
}
\addProblem{% 2017センター英語
  Rita: Daniel and I have to go home now.\par
  Father: Oh, \語順整序{{how come}{you}{are}{leaving}{earlier}{than}} usual? I thought you were going to stay for dinner.
}
\addProblem{% 2016センター英語
  Hotel clerk: Good evening, Mr.~and Mrs.~Gomez. How can I help you?\par
  Mrs.~Gomez: Well, \語順整序{{we're}{wondering}{if}{you}{could}{tell}} us how to get to the theater.
}
\addProblem{% 2016センター英語
  Student: Excuse me. I'd like to know what we will be discussing in next week's seminar.\par
  Professor: I haven't decided yet, so \語順整序{{let}{me}{send}{you}{the details}{by}} email.
}
\addProblem{% 2016センター英語
  Interviewer: How did you change after becoming the head of such a large company?\par
  President: I \語順整序{{came to}{realize}{the}{need}{to}{manage}} my time more effectively.
}

% 1〜\problemcount をシャッフル
\randomshuffle[name=shuffled]{1}{\problemcount}

\begin{document}
\printAllProblems
\end{document}

【出力例】

問題自体の順序,および問題内での語順の両方が,コンパイルするごとにランダムにシャッフルされて出題されていきます。

f:id:doraTeX:20190118131322p:plain


(後略)