Here's a slightly (over?)worked version of the table. I made it a bit more flexible regarding the number of rows and columns you can use.
The \cards command now takes an optional argument plus three mandatory arguments:
\cards[<key-val>]{<header row>}{<first column>}{<table body>}
The optional argument lets you set the separator using sep=<sep> (default is sep=|) and the alignment of the table cells using align=<token> (default is align=c). The <header row> is a list of <sep>-separated items which will be typeset at the top of the table, preceded by an empty cell. The <first column> is also a list of <sep>-separated items which will be typeset at each row of the table, starting from the second row.
The <table body> is a <sep>-separated list of M×N items (M and N are the number of items in the <header row> and <first column> lists) which will be added one by one to the table in row-major order (that is, the first M items are put in the first row, the next M items are put in the second row, and so on.
The table from your question can be typeset with (newlines added for clarity; spaces are trimmed around the items):
\cards{ lente | zomer | herfst | winter }
{ B | G | D | S }
{3|1|6|1|
2|2|3|2|
4|3|4|3|
5|7|5|4}
An example using the options:
\cards[sep = /, align = l]
{ foo / bar / baz }
{ F / B / B }
{1/2/3/
4/5/6/
7/8/9}
Output:

Code:
\documentclass{article}
\usepackage{booktabs}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l__forti_table_sep_tl
\tl_new:N \l__forti_table_align_tl
\tl_new:N \l__forti_table_temp_tl
\int_new:N \l__forti_table_ncols_int
\seq_new:N \g__forti_table_body_seq
\seq_new:N \g__forti_table_header_seq
\seq_new:N \g__forti_table_column_seq
\cs_generate_variant:Nn \seq_gset_split:Nnn { Nx }
\keys_define:nn { forti }
{
, sep .tl_set:N = \l__forti_table_sep_tl
, sep .initial:n = { | }
, sep .value_required:n = true
, align .tl_set:N = \l__forti_table_align_tl
, align .initial:n = { c }
, align .value_required:n = true
}
\NewDocumentCommand { \cards } { o m m m }
{
\group_begin:
\IfValueT {#1} { \keys_set:nn { forti } {#1} }
\forti_card_distribution:nnn {#2} {#3} {#4}
\group_end:
}
\cs_new_protected:Npn \forti_card_distribution:nnn #1 #2 #3
{
\__forti_seq_gset_split:Nn \g__forti_table_header_seq {#1}
\__forti_seq_gset_split:Nn \g__forti_table_column_seq {#2}
\__forti_seq_gset_split:Nn \g__forti_table_body_seq {#3}
\__forti_card_distribution_check_do:nnnN
{ \seq_count:N \g__forti_table_header_seq }
{ \seq_count:N \g__forti_table_column_seq }
{ \seq_count:N \g__forti_table_body_seq }
\__forti_card_distribution:nn
}
\cs_new_protected:Npn \__forti_seq_gset_split:Nn #1 #2
{ \seq_gset_split:Nxn #1 { \tl_use:N \l__forti_table_sep_tl } {#2} }
\cs_new_protected:Npn \__forti_card_distribution_check_do:nnnN #1 #2 #3 #4
{
\int_compare:nNnTF {#1*#2} = {#3}
{ #4 {#1} {#2} }
{
\msg_error:nnxx { forti } { wrong-number-of-items }
{ \int_eval:n {#1*#2} } {#3}
}
}
\cs_new_protected:Npn \__forti_card_distribution:nn #1 #2
{
\int_set:Nn \l__forti_table_ncols_int {#1}
\use:x
{
\exp_not:N \begin{tabular}
{ * { \int_eval:n {#1 + 1} } { \tl_use:N \l__forti_table_align_tl } }
}
\toprule
\c_alignment_token
\seq_use:Nn \g__forti_table_header_seq { \c_alignment_token } \\
\cmidrule { 2 - \int_eval:n {#1 + 1} }
\int_step_function:nN { #2 }
\__forti_typeset_table_row:n
\bottomrule
\end{tabular}
}
\cs_new_protected:Npn \__forti_typeset_table_row:n #1
{
\seq_gpop:NN \g__forti_table_column_seq \l__forti_table_temp_tl
\tl_use:N \l__forti_table_temp_tl
\int_step_function:nN { \int_use:N \l__forti_table_ncols_int }
\__forti_typeset_table_item:n
\\
}
\cs_new_protected:Npn \__forti_typeset_table_item:n #1
{
\seq_gpop:NN \g__forti_table_body_seq \l__forti_table_temp_tl
\use:x { \c_alignment_token \exp_not:V \l__forti_table_temp_tl }
}
\msg_new:nnn { forti } { wrong-number-of-items }
{ Wrong~number~of~items~`#2'.~The~table~has~`#1'~cells. }
\ExplSyntaxOff
\begin{document}
\cards{ lente | zomer | herfst | winter }
{ B | G | D | S }
{3|1|6|1|
2|2|3|2|
4|3|4|3|
5|7|5|4}
\cards[sep = /, align = l]
{ foo / bar / baz }
{ F / B / B }
{1/2/3/
4/5/6/
7/8/9}
\end{document}
And as requested, here's a version without the first column:

\documentclass{article}
\usepackage{booktabs}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l__forti_table_sep_tl
\tl_new:N \l__forti_table_align_tl
\tl_new:N \l__forti_table_temp_tl
\int_new:N \l__forti_table_ncols_int
\seq_new:N \g__forti_table_body_seq
\seq_new:N \g__forti_table_header_seq
\cs_generate_variant:Nn \seq_gset_split:Nnn { Nx }
\keys_define:nn { forti }
{
, sep .tl_set:N = \l__forti_table_sep_tl
, sep .initial:n = { | }
, sep .value_required:n = true
, align .tl_set:N = \l__forti_table_align_tl
, align .initial:n = { c }
, align .value_required:n = true
}
\NewDocumentCommand { \cards } { o m m }
{
\group_begin:
\IfValueT {#1} { \keys_set:nn { forti } {#1} }
\forti_card_distribution:nn {#2} {#3}
\group_end:
}
\cs_new_protected:Npn \forti_card_distribution:nn #1 #2
{
\__forti_seq_gset_split:Nn \g__forti_table_header_seq {#1}
\__forti_seq_gset_split:Nn \g__forti_table_body_seq {#2}
\__forti_card_distribution_check_do:nnN
{ \seq_count:N \g__forti_table_header_seq }
{ \seq_count:N \g__forti_table_body_seq }
\__forti_card_distribution:nn
}
\cs_new_protected:Npn \__forti_seq_gset_split:Nn #1 #2
{ \seq_gset_split:Nxn #1 { \tl_use:N \l__forti_table_sep_tl } {#2} }
\cs_new_protected:Npn \__forti_card_distribution_check_do:nnN #1 #2 #3
{
\int_compare:nNnTF { \int_mod:nn {#2}{#1} } = { 0 }
{ #3 {#1} {#2} }
{ \msg_error:nnxx { forti } { wrong-number-of-items } {#1} {#2} }
}
\cs_new_protected:Npn \__forti_card_distribution:nn #1 #2
{
\int_set:Nn \l__forti_table_ncols_int {#1}
\use:x
{
\exp_not:N \begin{tabular}
{ * { \int_eval:n {#1} } { \tl_use:N \l__forti_table_align_tl } }
}
\toprule
\seq_use:Nn \g__forti_table_header_seq { \c_alignment_token } \\
\midrule
\int_step_function:nN { #2/#1 }
\__forti_typeset_table_row:n
\bottomrule
\end{tabular}
}
\cs_new_protected:Npn \__forti_typeset_table_row:n #1
{
\int_step_function:nN { \l__forti_table_ncols_int }
\__forti_typeset_table_item:n
\\
}
\cs_new_protected:Npn \__forti_typeset_table_item:n #1
{
\seq_gpop:NN \g__forti_table_body_seq \l__forti_table_temp_tl
\use:x
{
\int_compare:nNnT {#1} > { 1 } { \c_alignment_token }
\exp_not:V \l__forti_table_temp_tl
}
}
\msg_new:nnn { forti } { wrong-number-of-items }
{ Wrong~number~of~items~`#2'.~The~table~has~`#1'~cells. }
\ExplSyntaxOff
\begin{document}
\cards{ lente | zomer | herfst | winter }
{3|1|6|1|
2|2|3|2|
4|3|4|3|
5|7|5|4}
\cards[sep = /, align = l]
{ foo / bar / baz }
{1/2/3/
4/5/6/
7/8/9}
\end{document}
\cards, or 20 items, instead of 16. Should the table change in size or should there be an error? – Phelype Oleinik Sep 24 '19 at 00:01