!['1,2,...,Nmax' 숫자에서 'Nchoose' 숫자를 쉼표로 구분한 목록에 대한 명령](https://rvso.com/image/475713/'1%2C2%2C...%2CNmax'%20%EC%88%AB%EC%9E%90%EC%97%90%EC%84%9C%20'Nchoose'%20%EC%88%AB%EC%9E%90%EB%A5%BC%20%EC%89%BC%ED%91%9C%EB%A1%9C%20%EA%B5%AC%EB%B6%84%ED%95%9C%20%EB%AA%A9%EB%A1%9D%EC%97%90%20%EB%8C%80%ED%95%9C%20%EB%AA%85%EB%A0%B9.png)
코드를 찾았어요여기@John Kormylo는 숫자 \Nchoose
에서 숫자를 선택하여 1,2,...,\Nmax
쉼표로 구분하여 제공합니다 \mylist
.
질문: 어떻게 만들 수 있나요?명령이것부터, 마치
\createlist{<name of list>}{<Nmax>}{<Nchoose>}
예를 들어 \createliste{pokerlist}{52}{6}
, 그래서 다음과 같이 말할 수 있습니다:
Show list: \pokerlist
또는 Third element is: \pgfmathparse{\pokerarray[2]} \pgfmathresult
('힌트' 참조)
등.
힌트 1:나는 그것이 필요하다배열로도, 하지만 그때는 말할 수 있을 것 같아요 \def\myarray{\mylist}
.
힌트 2:이 목록에는중복 없음(예를 들어 "1,2,2,2,5,6,7,8,9,10,11,12"는 허용되지 않습니다.)
\documentclass{article}
\usepackage{tikz}
% Choose \Ncoose from \Nmax
\pgfmathtruncatemacro\Nmax{52}%
\pgfmathtruncatemacro\Nchoose{12}%
\begin{document}
% List of \Ncoose from \Nmax:
\foreach \i in {1,...,\Nmax} {\expandafter\xdef\csname index\i\endcsname{\i}}% create indexes
\foreach \i in {1,...,\Nmax} {% randomise (last step redundant)
\pgfmathparse{random(\i,\Nmax)}%
\let\j=\pgfmathresult
\expandafter\let\expandafter\tempa\csname index\i\endcsname
\expandafter\let\expandafter\tempb\csname index\j\endcsname
\global\expandafter\let\csname index\i\endcsname=\tempb
\global\expandafter\let\csname index\j\endcsname=\tempa
}%
\xdef\mylist{\csname index1\endcsname}% create comma delimited list
\foreach \i in {2,...,\Nchoose} {\xdef\mylist{\mylist, \csname index\i\endcsname}}%
\section{{\Nchoose} random numbers from {1,2,\dots,\Nmax}}
\noindent\mylist
\section{{33} random numbers from {1,2,\dots,60}}
...
\section{{52} random numbers from {1,2,\dots,52}}
...
\end{document}
답변1
이를 위해 패키지 코드가 필요하지 않다고 생각합니다. LaTeX에는 모든 기능이 미리 정의되어 있습니다.
섞인 목록을 기반으로 중복된 답변이 없습니다.
이것은 목록 1..n을 만든 다음 그것을 섞고 첫 번째 m 항목을 가져옵니다.
\documentclass{article}
\ExplSyntaxOn
\cs_generate_variant:Nn \cs_set:Npn {Npe} % old latex
\cs_generate_variant:Nn \clist_set:Nn {Ne} % old latex
\cs_new:Npn \cis_comma_tmp:n #1 {#1,}
\cs_new:Npn \cis_comma_tmpb:n #1 {\seq_item:Nn \l_tmpa_seq {#1} , }
\NewDocumentCommand\createlist{mmm}{
\clist_set:Ne \l_tmpa_clist {
\int_step_function:nN {#2} \cis_comma_tmp:n
}
\seq_set_from_clist:NN \l_tmpa_seq \l_tmpa_clist
\seq_shuffle:N \l_tmpa_seq
\cs_set:Npe#1 {
\int_step_function:nN {#3-1} \cis_comma_tmpb:n
\seq_item:Nn \l_tmpa_seq {#3}
}
}
\ExplSyntaxOff
\begin{document}
\createlist\aaa{52}{12}
\typeout{\aaa}
\createlist\bbb{60}{33}
\typeout{\bbb}
\createlist\ccc{52}{52}
\typeout{\ccc}
\end{document}
생산
12,21,36,23,2,24,3,49,25,52,8,10
9,15,36,27,51,48,10,32,55,31,49,57,47,5,42,12,29,43,17,56,44,34,35,30,2,16,41,23,28,33,37,11,59
36,34,15,49,7,45,33,31,2,29,51,50,5,10,44,17,6,43,3,14,1,19,9,23,48,24,7,32,42
,28,11,46,16,35,40,27,18,20,4,30,26,12,25,52,21,41,38,47,8,39,22,13
원래 답변
,
그러면 다음과 같은 터미널 출력이 생성됩니다( 제거할 수 있지만 후행을 남겼습니다).
40,12,45,51,43,15,6,21,8,37,16,39,
38,6,24,59,19,50,51,37,28,10,46,17,49,23,33,47,60,45,36,43,1,56,9,33,52,6,45,2,
30,2,30,49,46,
52,9,27,42,37,7,8,34,31,21,6,36,18,22,7,46,7,50,39,9,29,44,10,2,41,21,44,18,11,
20,37,16,16,36,16,26,49,7,21,18,21,40,32,28,43,31,27,25,5,18,16,6,
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand\createlist{mmm}{
\cs_set:Npe#1{\prg_replicate:nn{#3}{\int_rand:n{#2},}}}
\ExplSyntaxOff
\begin{document}
\createlist\aaa{52}{12}
\typeout{\aaa}
\createlist\bbb{60}{33}
\typeout{\bbb}
\createlist\aaa{52}{52}
\typeout{\aaa}
\end{document}
이는 중복이 허용된다고 가정합니다.
그렇지 않은 경우 대신 \seq_suffle
시퀀스에 사용 1...N
하고 첫 번째 m
항목을 가져옵니다.
하나를 제거하고 기존 라텍스 버전을 ,
선언하는 버전e
\documentclass{article}
\ExplSyntaxOn
\cs_generate_variant:Nn \cs_set:Npn {Npe} % old latex
\NewExpandableDocumentCommand\createlist{mmm}{
\cs_set:Npe#1{\use:e{\exp_not:N\use_none:n\use:e{\prg_replicate:nn{#3}{,\int_rand:n{#2}}}}}}
\ExplSyntaxOff
\begin{document}
\createlist\aaa{52}{12}
\typeout{\aaa}
\createlist\bbb{60}{33}
\typeout{\bbb}
\createlist\aaa{52}{52}
\typeout{\aaa}
\end{document}
답변2
중복을 원하지 않는 경우 두 가지 전략이 있지만 David가 제안한 전략은 매우 큰 요인으로 인해 속도가 느립니다. 여기서는 두 가지 전략을 보여줍니다. 먼저 1부터 Nmax까지의 정수가 포함된 시퀀스가 생성된 다음 섞이고 첫 번째 Nmax 항목이 새 시퀀스에 저장됩니다. 두 번째 구현에서는 1부터 Nmax까지의 임의의 정수가 생성되어 아직 존재하지 않는 경우 시퀀스에 추가되며, Nmax 항목이 추가되면 프로세스가 중지됩니다.
\documentclass{article}
\usepackage{l3benchmark}
\ExplSyntaxOn
\NewDocumentCommand{\createlistA}{mmm}
{% #1 = list name, #2 = Nmax, #3 = Nchoose
\seq_clear:N \l_tmpa_seq
\int_step_inline:nn { #2 } { \seq_put_right:Nn \l_tmpa_seq { ##1 } }
\seq_shuffle:N \l_tmpa_seq
\seq_clear_new:c { l_cis_list_#1_seq }
\int_step_inline:nn { #3 }
{
\seq_put_right:ce { l_cis_list_#1_seq } { \seq_item:Nn \l_tmpa_seq { ##1 } }
}
}
\NewDocumentCommand{\createlistB}{mmm}
{% #1 = list name, #2 = Nmax, #3 = Nchoose
\seq_clear:N \l_tmpa_seq
\bool_until_do:nn { \int_compare_p:n { \seq_count:N \l_tmpa_seq = #3 } }
{
\tl_set:Ne \l_tmpa_tl { \int_rand:n { #2 } }
\seq_if_in:NVF \l_tmpa_seq \l_tmpa_tl { \seq_put_right:NV \l_tmpa_seq \l_tmpa_tl }
}
\seq_clear_new:c { l_cis_list_#1_seq }
\seq_set_eq:cN { l_cis_list_#1_seq } \l_tmpa_seq
}
\benchmark:n { \createlistA{testA}{200}{6} }
\benchmark:n { \createlistB{testB}{200}{6} }
\stop
벤치마크 결과는 다음과 같습니다.
0.00248 seconds (1.66e4 ops)
7.69e-5 seconds (511 ops)
Nmax=10이고 Nchoose=6인 경우 다음을 얻습니다.
1.33e-4 seconds (869 ops)
8.36e-5 seconds (556 ops)
따라서 Nmax가 작을 때 두 번째 전략도 승리합니다.
그러므로 나는 두 번째 전략을 택하겠다.
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\createlist}{mmm}
{% #1 = list name, #2 = Nmax, #3 = Nchoose
\cis_createlist:nnn { #1 } { #2 } { #3 }
}
\NewExpandableDocumentCommand{\listitem}{mm}
{% #1 = list name, #2 = item number
\seq_item:cn { l_cis_list_#1_seq } { #2 }
}
\NewExpandableDocumentCommand{\printlist}{m}
{
\seq_use:cn { l_cis_list_#1_seq } { ,~ }
}
\seq_new:N \l__cis_createlist_tmp_seq
\tl_new:N \l__cis_createlist_tmp_tl
\cs_new_protected:Nn \cis_createlist:nnn
{
\seq_clear:N \l__cis_createlist_tmp_seq
\bool_until_do:nn
{
\int_compare_p:nNn { \seq_count:N \l__cis_createlist_tmp_seq } = { #3 }
}
{
\tl_set:Ne \l__cis_createlist_tmp_tl { \int_rand:n { #2 } }
\seq_if_in:NVF \l__cis_createlist_tmp_seq \l__cis_createlist_tmp_tl
{
\seq_put_right:NV \l__cis_createlist_tmp_seq \l__cis_createlist_tmp_tl
}
}
\seq_clear_new:c { l_cis_list_#1_seq }
\seq_set_eq:cN { l_cis_list_#1_seq } \l__cis_createlist_tmp_seq
}
\ExplSyntaxOff
\newcommand{\Nmax}{52}
\newcommand{\Nchoose}{12}
\begin{document}
\section{{\Nchoose} random numbers from \{1,2,\dots,\Nmax\}}
\createlist{first}{\Nmax}{\Nchoose}
\printlist{first}
\section{33 random numbers from \{1,2,\dots,60\}}
\createlist{second}{60}{33}
\printlist{second}
\section{52 random numbers from \{1,2,\dots,52\}}
\createlist{third}{52}{52}
\printlist{third}
\end{document}
TeX Live 2020, 2021 또는 2022에서도 작동하려면 다음을 추가하세요.
\cs_generate_variant:Nn \tl_set:Nn { Ne }
후에 \ExplSyntaxOn
.
TeX Live 2018 또는 2019도 지원하려면 다음을 수행해야 합니다.
\usepackage{xparse}