Für die 4-Menge a,b,c,d gibt es die alt text 3-Kombinationen in lexikographischer Reihenfolge

1. a,b,c
2. a,b,d
3. a,c,d
4. b,c,d

Ich habe mich gefragt: kann man diese Ausgabe irgendwie mit foreach-Schleifen o.ä. erzeugen?

Hinweis: In meinem konkreten Problem geht es um die 455 3-Kombinationen einer 15-Menge: alt text

gefragt 07 Mär, 13:31

cis's gravatar image

cis
9.0k18193308
Akzeptiert: 69%

2

Ist das nicht eher eine Frage für ein Matheforum? Algorithmisch ist das IMHO so etwas wie:

Öffne in Overleaf
a=15
while a >= 3 {
  b=a-1
  while b >= 2 { 
    c=b-1
    while c >= 1 { 
      print a b c
      c=c-1
    }
    b=b-1
  }
  a=a-1
}

Wobei Du natürlich noch die Zahlen in Buchstaben wandeln musst.

(07 Mär, 14:38) Ijon Tichy

Naja, ich möchte das ja automatisch ausgeben mit LaTeX. Allerdings ist es vielleicht tatsächlich ein CAS-Problem.

(07 Mär, 15:45) cis

Die Antwort ist ja, und das Folgende ist ein Existenzbeweis (und nicht die eleganteste Möglichkeit).

Öffne in Overleaf
\documentclass{article}
\usepackage[margin=1in]{geometry}
\usepackage{pgffor}
\newcounter{mystep}
\newcounter{aux}
\begin{document}
\foreach \X [evaluate=\X as \Ymin using {int(\X+1)}] in {1,...,15}
{\foreach \Y [evaluate=\Y as \Zmin using {int(\X+1)}]in {\Ymin,...,15}
{\foreach \Z in {\Zmin,...,15}
{\ifnum\X<\Y
   \ifnum\Y<\Z
     \stepcounter{mystep}
     \arabic{mystep}:\setcounter{aux}{\X}\alph{aux}\setcounter{aux}{\Y}\alph{aux}\setcounter{aux}{\Z}\alph{aux}
   \fi
 \fi  
}}}
\end{document}

alt text

Und, wie saputello bereits demonstriert hat, braucht man keine packages dafür. Hier ist ein anderes Beispiel.

Öffne in Overleaf
\documentclass{article}
\usepackage[margin=1in]{geometry}
\newcounter{mystep}
\newcounter{X}
\newcounter{Y}
\newcounter{Z}
\begin{document}
\setcounter{X}{0}\setcounter{Y}{0}\setcounter{Z}{0}
\loop%
\stepcounter{X}\setcounter{Y}{\theX}%
{\loop% 
\stepcounter{Y}\setcounter{Z}{\theY}%
{\loop% 
\stepcounter{Z}%
 \stepcounter{mystep}\arabic{mystep}\alph{X}\alph{Y}\alph{Z}
\ifnum\number\value{Z}<15 \repeat%
}%
\ifnum\number\value{Y}<14 \repeat%
}%
\ifnum\number\value{X}<13 \repeat
\end{document}

EDIT: Von \theX auf \number\value{X} etc. umgestellt. Die Syntax wurde mir am 23.11.2018 von Ulrike Fischer in tex.se nahegelegt, und @saputello hat mich daran erinnert, dass in anderen Dokumenten, in denen \the umdefiniert wird, das schief gehen kann. Danke an Beide!

Permanenter link

beantwortet 08 Mär, 19:28

Murmeltier's gravatar image

Murmeltier
2.4k64

bearbeitet 10 Mär, 15:04

saputello's gravatar image

saputello
10.4k73659

Wow, das muss ich mir mal in Ruhe zu Gemüte führen.

(09 Mär, 07:18) cis

Ein gutes Zeichen für aktive Beteiligung, sich über für & wider auszutauschen ;-) ab und zu sind es Kleinigkeiten, und wenn es einem beim aktiven Lesen auffällt, gern als Kommentar anmerken als ignorieren, warum auch nicht. Wir wollen nicht übergenau sein, können aber gern Verbesserungen anmerken, die man gern als kollegiales Mitdenken und Besprechen am TeX-Stammtisch verstehen kann. Danke euch beiden!

(10 Mär, 12:47) stefan ♦♦

Eigentlich kann man den Algorithmus von Ijon auch direkt mit LaTeX, ganz ohne Pakete umsetzen. Ich drehe hier mal nur zur Vereinfachung die Schleifen um:

Öffne in Overleaf
\documentclass[a4paper]{article}

\makeatletter
\newcommand*{\whilenum}{\@whilenum}
\makeatother

\newcounter{a}\renewcommand*{\thea}{\alph{a}}
\newcounter{b}\renewcommand*{\theb}{\alph{b}}
\newcounter{c}\renewcommand*{\thec}{\alph{c}}
\newcounter{n}

\begin{document}

\raggedright
\setcounter{a}{1}
\setcounter{n}{1}
\whilenum \value{a}<14 \do {%
  \setcounter{b}{\numexpr \value{a}+1\relax}%
  \whilenum \value{b}<15 \do {%
    \setcounter{c}{\numexpr \value{b}+1\relax}%
    \whilenum \value{c}<16 \do {%
      \textbf{\then.} \thea\theb\thec\\
      \stepcounter{c}%
      \stepcounter{n}%
    }%
    \stepcounter{b}%
  }%
  \stepcounter{a}%
}

\end{document}

Oder mit LaTeX3 (dieses Mal nahezu wörtlich umgesetzt):

Öffne in Overleaf
\documentclass[a4paper]{article}

\usepackage{xparse}

\ExplSyntaxOn
\int_new:N \l__threeoffifteen_a_int
\int_new:N \l__threeoffifteen_b_int
\int_new:N \l__threeoffifteen_c_int
\int_new:N \l__threeoffifteen_n_int

\NewDocumentCommand \threeoffifteen { O{\\} }
{%
  \int_set:Nn \l__threeoffifteen_n_int { 1 }
  \int_set:Nn \l__threeoffifteen_a_int { 15 }
  \int_while_do:nn { \l__threeoffifteen_a_int >= 3 }
  {%
    \int_set:Nn \l__threeoffifteen_b_int { \l__threeoffifteen_a_int - 1 }
    \int_while_do:nn { \l__threeoffifteen_b_int >= 2 }
    {%
      \int_set:Nn \l__threeoffifteen_c_int { \l__threeoffifteen_b_int - 1 }
      \int_while_do:nn { \l__threeoffifteen_c_int >= 1 }
      {%
        \textbf{ \int_to_arabic:n { \l__threeoffifteen_n_int } . }
        \nobreakspace
        \int_to_alph:n { 16 - \l__threeoffifteen_a_int }
        \int_to_alph:n { 16 - \l__threeoffifteen_b_int }
        \int_to_alph:n { 16 - \l__threeoffifteen_c_int }
        #1
        \int_incr:N \l__threeoffifteen_n_int
        \int_decr:N \l__threeoffifteen_c_int
      }%
      \int_decr:N \l__threeoffifteen_b_int
    }
    \int_decr:N \l__threeoffifteen_a_int
  }
}
\ExplSyntaxOff

\begin{document}

\raggedright\threeoffifteen
%\noindent\threeoffifteen[ ]

\end{document}

Verwendet man die Zeile \noindent\threeaboutfifteen[ ] statt der Zeile \raggedright\theeaboutfifteen, ist die Ausgabe:

alt text

Eine Abwandlung für \threeofN, wobei N ein zusätzliches Argument im Wertebereich 3 <= N <= 26 ist, wäre dabei einfach umzusetzen.

Es muss also nicht immer pgf sein. Natürlich ist gut, wenn man pgf beherrscht. LaTeX3 zu lernen hat allerdings auch viele Vorteile.

Permanenter link

beantwortet 09 Mär, 07:28

saputello's gravatar image

saputello
10.4k73659

bearbeitet 20 Mär, 12:11

Jetzt fehlt eigentlich nur noch, dass @Henri eine schöne ConTeXt-Lösung erstellt. Wobei das vermutlich eigentlich eine Lua-Lösung wäre, die man daher auch mit LuaLaTeX-Umsetzen könnte. ;-)

(09 Mär, 07:36) saputello
Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs füge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×20
×11

Frage gestellt: 07 Mär, 13:31

Frage wurde angeschaut: 337 Mal

Zuletzt aktualisiert: 20 Mär, 12:11