![Befehl für eine kommagetrennte Liste von 'Nchoose'-Zahlen aus '1,2,...,Nmax'-Zahlen](https://rvso.com/image/475713/Befehl%20f%C3%BCr%20eine%20kommagetrennte%20Liste%20von%20'Nchoose'-Zahlen%20aus%20'1%2C2%2C...%2CNmax'-Zahlen.png)
Ich habe einen Code gefundenHier\Nchoose
von @John Kormylo, der Zahlen aus Zahlen auswählt 1,2,...,\Nmax
und sie durch Kommas getrennt ausgibt \mylist
.
Frage: Wie könnte ich eineBefehldavon, wie
\createlist{<name of list>}{<Nmax>}{<Nchoose>}
Zum Beispiel \createliste{pokerlist}{52}{6}
, sodass ich sagen kann:
Show list: \pokerlist
oder Third element is: \pgfmathparse{\pokerarray[2]} \pgfmathresult
(siehe „Hinweis“)
und so weiter.
Hinweis 1:ich brauche esauch als Array, aber ich denke, das kann ich \def\myarray{\mylist}
dann sagen.
Hinweis 2:In diesen Listen sindkeine Duplikate(Beispielsweise ist „1,2,2,2,5,6,7,8,9,10,11,12“ NICHT zulässig.)
\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}
Antwort1
Ich glaube nicht, dass Sie hierfür Paketcode benötigen, da LaTeX alle Funktionen vordefiniert hat.
Keine doppelte Antwort basierend auf einer gemischten Liste
Dies erzeugt eine Liste 1..n, mischt sie dann und nimmt die ersten m Einträge
\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}
Produktion
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
ursprüngliche Antwort
Dies erzeugt die folgende Terminalausgabe (ich habe die folgenden Zeichen gelassen, ,
obwohl sie entfernt werden könnten)
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}
Dies setzt voraus, dass Duplikate zulässig sind.
Wenn nicht, dann verwenden Sie es stattdessen \seq_suffle
für eine Sequenz 1...N
und nehmen Sie dann die ersten m
Elemente.
Eine Version, die eine entfernt und Versionen für altes Latex ,
deklarierte
\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}
Antwort2
Wenn Sie keine Duplikate möchten, haben Sie zwei Strategien, aber die von David vorgeschlagene ist um einen sehr großen Faktor langsamer. Hier zeige ich zwei Strategien: Bei der ersten wird die Sequenz mit den Ganzzahlen von 1 bis Nmax generiert, dann gemischt und die ersten Nmax-Elemente werden in einer neuen Sequenz gespeichert; bei der zweiten Implementierung wird eine zufällige Ganzzahl von 1 bis Nmax generiert und der Sequenz hinzugefügt, wenn sie nicht bereits vorhanden ist. Der Prozess wird beendet, wenn Nmax-Elemente hinzugefügt wurden.
\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
Das Ergebnis des Benchmarks ist
0.00248 seconds (1.66e4 ops)
7.69e-5 seconds (511 ops)
Für Nmax=10 und Nchoose=6 erhalten wir
1.33e-4 seconds (869 ops)
8.36e-5 seconds (556 ops)
daher gewinnt die zweite Strategie auch, wenn Nmax klein ist.
Daher werde ich mich für die zweite Strategie entscheiden.
\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}
Wenn dies auch mit TeX Live 2020, 2021 oder 2022 funktionieren soll, fügen Sie hinzu
\cs_generate_variant:Nn \tl_set:Nn { Ne }
nach \ExplSyntaxOn
.
Wenn Sie auch TeX Live 2018 oder 2019 unterstützen möchten, müssen Sie
\usepackage{xparse}