Skip to content

Instantly share code, notes, and snippets.

@doraTeX
Last active December 8, 2023 04:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doraTeX/6b2b7abe1baaa5251006115348684dfe to your computer and use it in GitHub Desktop.
Save doraTeX/6b2b7abe1baaa5251006115348684dfe to your computer and use it in GitHub Desktop.
A LaTeX package for random shuffling
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{randomshuffle}[2019/01/18 v0.2]
\RequirePackage{keyval}
\ifdefined\pdfuniformdeviate
\let\randomshuffle@uniformdeviate\pdfuniformdeviate
\let\randomshuffle@setrandomseed\pdfsetrandomseed
\else\ifdefined\uniformdeviate
\let\randomshuffle@uniformdeviate\uniformdeviate
\let\randomshuffle@setrandomseed\setrandomseed
\else
\PackageError{randomshuffle}{\detokenize{This LaTeX engine does not support \pdfuniformdeviate nor \uniformdeviate}}\@ehc
\fi\fi
\newcount\randomshuffle@first
\newcount\randomshuffle@last
\newcount\randomshuffle@k
\newcount\randomshuffle@t
\newcount\randomshuffle@j
%%% 1以上#1以下の乱数を生成する
\def\randomshuffle@rand#1{\the\numexpr\randomshuffle@uniformdeviate\numexpr#1\relax+\@ne\relax}
\def\randomshuffle@swap#1#2#3{%
\edef\randomshuffle@temp{\csname#1@\the#2\endcsname}%
\expandafter\xdef\csname#1@\the#2\endcsname{\csname#1@\the#3\endcsname}%
\expandafter\xdef\csname#1@\the#3\endcsname{\randomshuffle@temp}%
}
\def\randomshuffle@name{shuffled}
\def\randomshuffle@inverse@suffix{inverse}
\define@key{randomshuffle@parameters}{seed}{\randomshuffle@setrandomseed#1\relax}
\define@key{randomshuffle@parameters}{name}{\edef\randomshuffle@name{#1}}
\define@key{randomshuffle@parameters}{inversesuffix}{\edef\randomshuffle@inverse@suffix{#1}}
\newcommand*\randomshuffle[3][]{%
\setkeys{randomshuffle@parameters}{#1}%
\randomshuffle@first=\numexpr#2\relax
\randomshuffle@last=\numexpr#3\relax
%% 呼び出し用の命令を作成
%%% 正写像アクセサ
\expandafter\global\expandafter\@namedef\expandafter{\expandafter\randomshuffle@name\expandafter}\expandafter##\expandafter1\expandafter{\expandafter\csname\randomshuffle@name @##1\endcsname}%
%%% 逆写像アクセサ
\edef\randomshuffle@inverse{\randomshuffle@name\randomshuffle@inverse@suffix}%
\expandafter\global\expandafter\@namedef\expandafter{\expandafter\randomshuffle@inverse\expandafter}\expandafter##\expandafter1\expandafter{\expandafter\csname\randomshuffle@inverse @##1\endcsname}%
%%% 写像の初期化
\randomshuffle@k=\randomshuffle@first
{\loop
\global\randomshuffle@t=\numexpr\randomshuffle@k-\randomshuffle@first+\@ne\relax
\expandafter\xdef\csname\randomshuffle@name @\the\randomshuffle@t\endcsname{\the\randomshuffle@k}% 正写像アクセサを初期化
\expandafter\xdef\csname\randomshuffle@name\randomshuffle@inverse@suffix @\the\randomshuffle@t\endcsname{\the\randomshuffle@k}% 逆写像アクセサを初期化
\advance\randomshuffle@k\@ne
\unless\ifnum\randomshuffle@k>\randomshuffle@last\repeat}%
%
%%% 正写像にあたる置換の生成
\let\randomshuffle@list\@empty
\randomshuffle@j=\randomshuffle@t% j=tから下げていく
{\loop
\randomshuffle@k=\randomshuffle@rand{\randomshuffle@j}% 1以上j以下の乱数kを取得
\randomshuffle@swap{\randomshuffle@name}{\randomshuffle@j}{\randomshuffle@k}% j番目とk番目を交換
\xdef\randomshuffle@list{{\the\randomshuffle@k}\randomshuffle@list}% 生成した乱数を既存乱数列の先頭にpush
\advance\randomshuffle@j\m@ne% jを1減じる
\ifnum\randomshuffle@j>\@ne\repeat}%
%
%%% 逆写像にあたる置換の生成
\randomshuffle@j=\tw@% j=2から上げていく
\expandafter\@tfor\expandafter\randomshuffle@r\expandafter:\expandafter=\randomshuffle@list\do{%
\randomshuffle@swap{\randomshuffle@name\randomshuffle@inverse@suffix}{\numexpr\randomshuffle@r\relax}{\randomshuffle@j}% 現行の逆写像に 互換 (j, 乱数) を合成
\advance\randomshuffle@j\@ne% jを1増やす
}%
}
\endinput
%#!uplatex
\documentclass[uplatex]{jsarticle}
\usepackage{randomshuffle}
\makeatletter
\newcount\problemnum
\def\addProblem#1#2{%
\advance\problemnum\@ne
\@namedef{problem\the\problemnum}{#1}%
\@namedef{answer\the\problemnum}{#2}%
}
\def\printProblem#1{\@nameuse{problem\shuffled{#1}}}
\def\printAnswer#1{\@nameuse{answer\shuffled{#1}}}
\makeatother
\addProblem{アルカリ土類金属は,すべて遷移元素である。}{×}
\addProblem{典型元素には,両性元素が含まれる。}{○}
\addProblem{遷移元素は,すべて金属元素である。}{○}
\addProblem{典型元素では,周期表の左下に位置する元素ほど陽性が強い。}{○}
\addProblem{遷移元素には,複数の酸化数をとるものがある。}{○}
\addProblem{密閉容器に入れてある物質が気液平衡の状態にあるとき,単位時間当たりに液体から蒸発する分子の数と,気体から凝縮する分子の数は等しい。}{○}
\addProblem{無極性分子の気体が凝縮して液体になる現象には,分子間にはたらくファンデルワールス力が関わっている。}{○}
\addProblem{純溶媒の沸点は,その純溶媒に不揮発性の溶質が溶けた溶液の沸点よりも低い。}{○}
\addProblem{純物質は,三重点で気体・液体・固体が共存する平衡状態をとる。}{○}
\addProblem{純物質は,液体の状態で凝固点より低い温度になることはない。}{×}
\addProblem{フッ素は,ハロゲンの単体の中で,水素との反応性が最も高い。}{○}
\addProblem{フッ化水素酸は,ガラスを腐食する。}{○}
\addProblem{塩化銀は,アンモニア水に溶ける。}{○}
\addProblem{次亜塩素酸は,塩素がとりうる最大の酸化数をもつオキソ酸である。}{×}
\addProblem{ヨウ化カリウム水溶液にヨウ素を溶かすと,その溶液は褐色を呈する。}{○}
% 1〜\problemnum をシャッフルして \shuffled でアクセス
\randomshuffle[name=shuffled]{1}{\problemnum}
\begin{document}
\section{問題}
次の各記述が正しければ○,誤っていれば×と答えよ。
\begin{enumerate}
\item \printProblem{1}
\item \printProblem{2}
\item \printProblem{3}
\item \printProblem{4}
\item \printProblem{5}
\end{enumerate}
\section{解答}
\begin{enumerate}
\item \printAnswer{1}
\item \printAnswer{2}
\item \printAnswer{3}
\item \printAnswer{4}
\item \printAnswer{5}
\end{enumerate}
\end{document}
%#!uplatex
\documentclass[uplatex]{jsarticle}
\usepackage{randomshuffle}
\makeatletter
\newcount\wordnum
\newcount\wordcount
% 選択肢の記号を ㋐, ㋑, …… で出力する
\def\MaruKata#1{\chardef\@labelchar=\expandafter\ucs\numexpr13007+#1\relax\textgt{\@labelchar}}
%% 語群のインプットと空欄出力
\def\語順整序#1{%
\wordnum=\z@
\@tfor\word:=#1\do{%
\advance\wordnum\@ne
\edef\thisword{word\the\wordnum}%
\expandafter\@namedef\expandafter{\expandafter\thisword\expandafter}\expandafter{\word}% 単語を登録
\space\framebox[1cm][c]{\texttt{\the\wordnum}}\space% 空欄出力
}%
\wordcount=\wordnum% 単語数を保存
\randomshuffle[name=shuffled]{1}{\wordcount}% 語群をランダムシャッフル
}
%% シャッフルされた語群を出力
\def\語群出力{%
\par\noindent\textgt{《語群》}\par\nopagebreak
\wordnum=\z@
\loop
\advance\wordnum\@ne
\def\thisword{\@nameuse{word\shuffled{\the\wordnum}}}% シャッフルされた選択肢の内容
\makebox[\dimexpr\linewidth/\wordcount\relax][l]{\MaruKata{\wordnum}\kern1zw\relax\thisword}% 選択肢を出力
\ifnum\wordcount>\wordnum\repeat
}
%% 逆置換を用いて正解を出力
\def\解答出力{%
\par\noindent\textgt{【解答】}\par\nopagebreak
\wordnum=\z@
\loop
\advance\wordnum\@ne
\def\answernum{\shuffledinverse{\the\wordnum}}% 正解選択肢の番号
\texttt{\the\wordnum:} \MaruKata{\answernum}% 正解の記号を出力
\qquad
\ifnum\wordcount>\wordnum\repeat
}
\makeatother
\begin{document}
\section*{2016年センター英語 第2問B 問1}
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.
\語群出力
\解答出力
\section*{2016年センター英語 第2問B 問2}
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.
\語群出力
\解答出力
\section*{2016年センター英語 第2問B 問3}
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.
\語群出力
\解答出力
\end{document}
%#!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}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment