The following does produce the output you want. The minus signs in the output are not contributing to the overall size of the output, so they might stick into the margin. As you said you don't need fractions, the following doesn't cover that. It is only working for integer division and always truncates the result. Some portions of the horizontal rules might get drawn twice, that can lead to rendering issues in some PDF viewers, but if you zoom in those should be gone and the print should look fine.
\documentclass[]{article}
\usepackage{xparse,expl3}
\usepackage{mathtools}
\ExplSyntaxOn
\int_new:N \l_Simeon_divisor_int
\int_new:N \l_Simeon_tmpa_int
\int_new:N \l_Simeon_next_dividend_int
\int_new:N \l_Simeon_pops_int
\seq_new:N \l_Simeon_dividend_seq
\seq_new:N \l_Simeon_under_seq
\bool_new:N \l_Simeon_first_bool
\tl_new:N \l_Simeon_tmpa_tl
\msg_new:nnn { Simeon } { empty~arg }%>>>
{
It ~ seems ~ like ~ you ~ provided ~ an ~ empty ~ arg ~ for ~ the ~ #1, ~
this ~ is ~ not ~ allowed.
}%<<<
\cs_new:Npn \Simeon_shift_aux:n #1%>>>
{
\exp_not:n { \phantom { 0 } }
}%<<<
\cs_new:Npn \Simeon_shift:%>>>
{
\int_step_function:nN { \l_Simeon_pops_int } \Simeon_shift_aux:n
}%<<<
\cs_new_protected:Npn \Simeon_array:n #1%>>>
{
\mathllap { \begin { array } { @{} r @{} } #1 \end { array } }
}%<<<
\cs_new_protected:Npn \Simeon_add_to_under:n #1%>>>
{
\seq_put_right:Nx \l_Simeon_under_seq
{
\Simeon_shift:
\Simeon_array:n { #1 }
}
}%<<<
\cs_new_protected:Npn \Simeon_pop_and_calc:nn #1 #2%>>>
{
\seq_pop_left:NN \l_Simeon_dividend_seq \l_Simeon_tmpa_tl
\int_incr:N \l_Simeon_pops_int
\int_set:Nn \l_Simeon_next_dividend_int
{ \l_Simeon_next_dividend_int * 10 + \l_Simeon_tmpa_tl }
\int_set:Nn \l_Simeon_tmpa_int
{
\fp_eval:n
{ trunc ( \l_Simeon_next_dividend_int / \l_Simeon_divisor_int ) }
}
\int_compare:nNnF \l_Simeon_tmpa_int = \c_zero_int
{
#1
\int_set:Nn \l_Simeon_tmpa_int
{ \l_Simeon_tmpa_int * \l_Simeon_divisor_int }
\Simeon_add_to_under:n { #2 }
\int_set:Nn \l_Simeon_next_dividend_int
{ \l_Simeon_next_dividend_int - \l_Simeon_tmpa_int }
}
}%<<<
\cs_new:Npn \Simeon_continue_hline:%>>>
{
\noalign { \vskip -\arrayrulewidth }
\hline
}%<<<
\NewDocumentCommand \longintdiv { m m }%>>>
{
% initializing variables >>>
\tl_if_blank:nT { #1 }
{ \msg_error:nnn { Simeon } { empty~arg } { dividend } }
\tl_if_blank:nT { #2 }
{ \msg_error:nnn { Simeon } { empty~arg } { divisor } }
\seq_set_split:Nnn \l_Simeon_dividend_seq {} { #1 }
\seq_clear:N \l_Simeon_under_seq
\int_set:Nn \l_Simeon_divisor_int { #2 }
\int_zero:N \l_Simeon_next_dividend_int
\int_zero:N \l_Simeon_pops_int
\bool_set_true:N \l_Simeon_first_bool
% <<<
% first division >>>
\bool_do_while:nn
{ \l_Simeon_first_bool && !\seq_if_empty_p:N \l_Simeon_dividend_seq }
{
\Simeon_pop_and_calc:nn { \bool_set_false:N \l_Simeon_first_bool }
{
\exp_not:N \mathllap { {} - {} }
\int_use:N \l_Simeon_tmpa_int
\exp_not:n { \\ \hline }
}
}
% <<<
% other divisions >>>
\bool_while_do:nn { !\seq_if_empty_p:N \l_Simeon_dividend_seq }
{
\Simeon_pop_and_calc:nn {}
{
\exp_not:N \Simeon_continue_hline:
\int_use:N \l_Simeon_next_dividend_int
\exp_not:n { \\ \mathllap { {} - {} } }
\int_use:N \l_Simeon_tmpa_int
\exp_not:n { \\ \hline }
}
}
% <<<
% rest >>>
\Simeon_add_to_under:n
{
\exp_not:N \Simeon_continue_hline:
\int_use:N \l_Simeon_next_dividend_int
}
% <<<
% output >>>
$
\begin { array } [ t ] { @{} l @{} }
#1 \mathbin{:} #2 = \int_eval:n { \fp_eval:n { trunc ( #1 / #2 ) } }\\
\seq_use:Nn \l_Simeon_under_seq { \\ }
\end { array }
$
% <<<
}%<<<
\ExplSyntaxOff
\begin{document}
\longintdiv{1011}{11}
\qquad
\longintdiv{3516}{5}
\qquad
\longintdiv{5}{5}
\qquad
\longintdiv{4}{5}
\end{document}
