O Protocolo do Mictório

38

fundo

O chamado "Protocolo do Urinol", que descreve a ordem em que os urinóis individuais são colhidos no banheiro masculino, foi discutido em vários lugares. Uma versão é fornecida nesta postagem do blog xkcd . Esta pergunta diz respeito a uma ligeira variação:

Arranjo : n mictórios em uma linha.
Protocolo : cada nova pessoa seleciona um dos mictórios mais distantes daqueles já em uso.

Observe que isso não impõe restrições sobre a escolha do mictório pela primeira pessoa.

Atualização : A sequência do número de maneiras diferentes pelas quais n pessoas podem selecionar n urinóis começa com 1, 2, 4, 8, 20 ... Observe que isso não é o mesmo que OEIS A095236 , que descreve restrições um pouco mais rigorosas do que neste questão.

Tarefa

Dado um número n entre 0 e 10, produza (em qualquer ordem) todas as ordens possíveis nas quais n pessoas podem ocupar n urinóis. Cada pedido deve ser impresso como o arranjo final: uma sequência de dígitos representando as pessoas (1-9 para as primeiras 9 pessoas, 0 para o décimo), começando no urinol mais à esquerda, com separadores não alfanuméricos opcionais entre (mas não antes) ou depois) os dígitos. Por exemplo, as seguintes saídas são válidas:

>> 3
132
213
312
231

>> 4
1|3|4|2
1|4|3|2
3|1|4|2
4|1|3|2
2|3|1|4
2|4|1|3
2|3|4|1
2|4|3|1

Você pode escrever um programa ou função, recebendo informações via STDIN (ou alternativa mais próxima), argumento de linha de comando ou argumento de função. Os resultados devem ser impressos em STDOUT (ou alternativa mais próxima).

Pontuação

O menor código vence. Aplicam-se os termos e condições padrão.

Uri Granta
fonte
1
Hum. Por 5 mictórios, eu entendo isso . Em vez disso, deve ter 16 linhas. Alguém poderia por favor elaborar quais dessas soluções estão erradas? No momento, isso está implementando: Escolha qualquer um dos mictórios com distância máxima de qualquer outra pessoa.
Knedlsepp 18/03/2015
1
. Tanto para sandboxing :-( Spec é como descrito na tarefa, não a definição sequência Vou atualizar assim que chegar a um computador.
Uri Granta
1
@knedlsepp As linhas 3, 4, 17, 18 estão incorretas. Nestas, você coloca a pessoa nº 3 em um spancomprimento 1, onde há um spancomprimento 2 disponível. De repente, consegui me confundir. Parece que o OP é intencionalmente derivado do link e, portanto, o link deve ser seguido?
BrainSteel
Especificações atualizadas para observar que a tarefa não é a mesma que A095236.
Uri Granta
É permitido gerar o formato em [1, 3, 2], onde cada solução é separada por novas linhas? (portanto, não apenas um separador de ",", mas também o início de "[" e o final de "]"))
orlp

Respostas:

11

Pyth, 53 51

MhSm^-dG2HjbmjdmehxkbQusmm+dkfqgTdeSmgbdQUQGUtQm]dQ

Essa é uma abordagem iterativa. Dado um possível conjunto de locais ordenados parcialmente preenchidos, encontramos todos os locais adicionais ideais, depois geramos a lista de locais correspondentes e repetimos.

Os resultados são gerados no formulário e [<first person's location>, <second person's location> ...], em seguida, isso é transformado no formato desejado. MhSm^-dG2Hdefine uma função auxiliar que encontra as distâncias mínimas de uma determinada paralisação a uma paralisação ocupada (ao quadrado). Divertidamente, o separador é gratuito.

Exemplo de execução.

Explicação:

Primeiro, a função auxiliar g, que encontra a distância quadrática mínima entre G e qualquer valor em H.

MhSm^-dG2H
M             def g(G,H): return
 hS           min(                         )
   m     H        map(lambda d:        , H) 
    ^-dG2                      (d-G)**2

Em seguida, encontramos as localizações máximas acima do urinol da distância quadrática mínima entre esse urinol e qualquer urinol ocupado:

( Qé a entrada.)

eSmgbdQ
eS          max(                                   )
  m   Q         map(lambda b:      , range(len(Q)))
   gbd                       g(b,d)

dneste caso, é a lista de mictórios ocupados, enquanto bitera sobre os locais do mictório.

Em seguida, encontramos todos os locais do urinol cuja distância ao quadrado mínima do urinol ocupado mais próximo é igual ao valor máximo encontrado acima.

fqgTdeSmgbdQUQ
f           UQ    filter(lambda T:                             , range(len(Q)))
 qgTd                             g(T,d) ==
     eSmgbdQ                                <value found above>

Em seguida, geraremos as listas de locais do mictório criadas adicionando os locais do mictório encontrados acima a d. Faremos isso para cada lista anterior de localizações de urinol, estendendo assim as listas de comprimento Npara N+1. Gé a lista de listas legais de locais de mictório ocupados de um determinado comprimento.

smm+dkfqgTdeSmgbdQUQG
sm                  G    sum(map(lambda d:                               ,G)
  m+dk                                   map(lambda k:d+[k],            )
      fqgTdeSmgbdQUQ                                        <above list>

Em seguida, aplicaremos a expressão acima repetidamente, para gerar a lista completa de listas de locais ocupados no mictório. u, a função reduzir, faz exatamente isso, quantas vezes houver elementos em seu segundo argumento.

usmm+dkfqgTdeSmgbdQUQGUtQm]dQ
usmm+dkfqgTdeSmgbdQUQG           reduce(lambda G,H: <the above expression)
                      UtQ        repeat Q-1 times
                         m]dQ    starting with [[0], [1], ... [Q-1]]. 

Converta da representação acima, que vai [<1st location>, <2nd location>, ... ]para o formato de saída desejado [<person in slot 1>, <person in slot 2>, ... ],. Em seguida, o formulário de saída é unido à string de saída e impresso. A impressão está implícita.

jbmjdmehxkbQ
jbm             '\n'.join(map(λ k:                                    ,<above>)
   jdm     Q                      ' '.join(map(λ b:                ,Q)
        xkb                                        b.index(k)
      eh                                                     +1 %10
isaacg
fonte
Porra, eu deveria parar de escrever soluções recursivas em Pyth. Eu sempre sou
derrotado
kajsdlkas^23asdjkla1lasdkj~JZasSSA- quase metade do tamanho.
Optimizer
@ Otimizador Vou adicionar uma explicação quando estiver menos ocupado.
Isaacg
8

Pitão, 75 71 67

DcGHFk_UQJf!s:GeS,0-TkhS,h+TklGUQIJRsmcX>G0dhHhHJ)R]Gjbmjdmebkcm0Q0

Solução combinatória recursiva.

É uma tradução bastante direta desta solução Python:

N = int(input())

def gen(l, p):
    for d in reversed(range(N)):
        s = []
        for i in range(N):
            if not sum(l[max(0,i-d):min(i+d+1, len(l))]):
                s.append(i)

        if s:
            r = []
            for possib in s:
                j = l[:]
                j[possib] = p+1
                r += gen(j, p+1)

            return r

    return [l]

print("\n".join(" ".join(str(x % 10) for x in sol) for sol in gen([0] * N, 0)))
orlp
fonte
Como isso funciona? Em mais detalhes do que "solução combinatória recursiva".
tbodt
@tbodt Adicionado o código Python que escrevi antes de traduzir para Pyth.
orlp
5

C, 929 878 bytes

Este é um monstro, pessoal. Desculpe.

typedef unsigned long U;typedef unsigned char C;U f(int*u,n){C c[8],a[8];*(U*)(&c)=-1;int i,b=0,l=-9,s=-2,f=0,d;for (i=0; i<n; i++) {if (!u[i]&&s<0)s=i,l=0;if(!u[i])l++;if(u[i]&&s>=0){if(!s)l=2*l-1;d=(l-1)/2;if(b<d)*(U*)(a)=0,*(U*)(c)=-1,*c=s,*a=l,f=1,b=d;else if(b==d)c[f]=s,a[f++]=l;s=-1;}}if(s>=0&&l){l=2*l-1;d=(l-1)/2;if(b<d)*(U*)(c)=-1,*c=s,*a=l,f=1,b=d;else if(b==d)c[f]=s,a[f++]=l;}d=f;for(i=0;i<d;i++){if((c[i]+1)&&c[i]){if(c[i]+a[i]==n)c[i]=n-1;else{if(!(a[i]%2))c[f++]=b+c[i]+1;c[i]+=b;}}}return*(U*)c;}void P(int*u,n,i,c,m){for(i=0;i<n;i++){if(!u[i])c++;if(u[i]>m)m=u[i];}if(!c){for(i=0;i<n;i++)printf("%d",u[i]==10?0:u[i]);printf("\n");}else{int s[8][n];for(i=0;i<8;i++)for(c=0;c<n;c++)s[i][c]=u[c];U t=f(u,n);C*H=&t;for(i=0;i<8;i++)if((C)(H[i]+1))s[i][H[i]]=m+1,P(s[i],n,0,0,0);}}void L(n){int u[n],i,j;for(i=0;i<n;i++){for(j=0;j<n;j++)u[j]=j==i?1:0;P(u,n,0,0,0);}}

Define 3 funções, f(int*,int) , P(int*,int,int,int,int), e L(int). Ligue L(n)e ele gera STDOUT.

Saída para n=5:

14352
15342
31452
31542
41352
51342
41532
51432
24153
25143
34152
35142
23415
23514
24513
25413
24315
25314
24351
25341

Atualização: removi os separadores e consertei o código. O código antigo não apenas falhou para n = 7 +, mas também não produziu nada para n = 10 (oops!). Eu testei mais detalhadamente esse grupo. Agora ele suporta entradas de até n = 13 (embora a "%d"alteração deva ser alterada para"%x" para que seja impresso em hexadecimal). O tamanho da entrada depende sizeof(long)e supõe-se que esteja 8na prática.

Aqui está uma explicação de como funciona e por que existe uma restrição tão estranha:

Como eles foram usados ​​muito, por isso os definimos para salvar alguns bytes:

typedef unsigned long U; typedef unsigned char C;

Aqui está f:

U f(int*u,n){
    C c[8],a[8];
    *(U*)(&c)=-1;
    int i,b=0,l=-9,s=-2,f=0,d;
    for (i=0; i<n; i++) {
        if (!u[i]&&s<0)
            s=i,l=0;
        if(!u[i])
            l++;
        if(u[i]&&s>=0){
            if(!s)
                l=2*l-1;
            d=(l-1)/2;
            if(b<d)
                *(U*)(a)=0,
                *(U*)(c)=-1,
                *c=s,
                *a=l,
                f=1,
                b=d;
            else if(b==d)
                c[f]=s,a[f++]=l;
            s=-1;
        }
    }
    if(s>=0&&l){
        l=2*l-1;
        d=(l-1)/2;
        if(b<d)
            *(U*)(c)=-1,
            *c=s,
            *a=l,
            f=1,
            b=d;
        else if(b==d)
            c[f]=s,a[f++]=l;
    }
    d=f;
    for(i=0;i<d;i++){
        if((c[i]+1)&&c[i]){
            if(c[i]+a[i]==n)
                c[i]=n-1;
            else{
                if(!(a[i]%2))
                    c[f++]=b+c[i]+1;
                c[i]+=b;
            }
        }
    }
    return*(U*)c;
}

fpega uma matriz de números inteiros de tamanho ne nela própria. A única parte inteligente aqui é que ele retorna um unsigned long, que é convertido em umchar[8] pela função de chamada. Cada caractere na matriz é, portanto, definido como 0xFFou para um índice apontando para um urinol válido para a próxima pessoa. Pois n<10, nunca precisamos de mais de 5 bytes para armazenar todos os urinóis válidos que a próxima pessoa possa usar.

Aqui está P:

void P(int*u,n,i,c,m){
    for(i=0;i<n;i++){
        if(!u[i])c++;
        if(u[i]>m)m=u[i];
    }
    if(!c){
        for(i=0;i<n;i++)
            printf("%d",u[i]==10?0:u[i]);
        printf("\n");
    }
    else{
        int s[8][n];
        for(i=0;i<8;i++)
            for(c=0;c<n;c++)
                s[i][c]=u[c];
        U t=f(u,n);
        C*H=&t;
        for(i=0;i<8;i++)
            if((C)(H[i]+1))
                s[i][H[i]]=m+1,P(s[i],n,0,0,0);
    }
}

Pusa uma matriz ude tamanho nem que exatamente um elemento está definido como1 e o restante está 0. Em seguida, ele encontra e imprime todas as permutações possíveis recursivamente.

Aqui está L:

void L(n){
    int u[n],i,j;
    for(i=0;i<n;i++){
        for(j=0;j<n;j++)
            u[j]=j==i?1:0;
        P(u,n,0,0,0);
    }
}

L simplesmente chama P n horários com diferentes posições iniciais a cada vez.

Para os interessados, isso (menos golfe) fgerará a sequência em A095236 .

U f(int*u,n) {
    C c[8];
    *(U*)(&c) = -1;
    int i,b=0,l=-10,s=-2,f=0,d;
    for (i=0; i<n; i++) {
        if (!u[i]&&s<0) {
            s=i,l=0;
        }
        if(!u[i]){
            l++;
        }
        if (u[i]&&s>=0) {
            if (!s) {
                l=2*l-1;
            }
            if (b<l) {
                *(U*)(&c)=-1;
                c[0]=s;
                f=1;
                b=l;
            }
            else if (b==l)
                c[f++]=s;
            s=-1;
        }
    }
    if (s>=0&&l) {
        l=2*l-1;
        if (b<l) {
            *(U*)(&c)=-1;
            c[0]=s;
            f=1;
            b=l;
        }
        else if (b==l)
            c[f++]=s;
    }
    d=f;
    for (i=0; i<d; i++) {
        if ((c[i]+1)&&c[i]) {
            if (c[i]+b==n) {
                c[i]=n-1;
            }
            else{
                if (!(b%2)) {
                    c[f++]=(b-1)/2+c[i]+1;
                }
                c[i]+=(b-1)/2;
            }
        }
    }
    return *(U*)c;
}
BrainSteel
fonte
"1 4 ..." no início parece contrário às especificações: se o primeiro número for 1, o próximo deverá ser 5.
anatolyg
2
@anatolyg No. Aqui está uma explicação passo a passo de como "1 4" pode acontecer: gist.github.com/orlp/a5706ba664b70209b48a
orlp
Lembre-se, os separadores são opcionais. Você pode salvar 1 byte, removendo o espaço após o% d :-) (!)
Uri Granta
@UriZarfaty Thanks! Na verdade, há uma tonelada de bytes a serem salvos aqui. Atualmente, estou escrevendo uma solução melhor e uma explicação.
BrainSteel
@yo 'Eu acho que você está confundindo um pouco a saída. Uma saída da 14352pessoa número 1 escolheu o urinol mais à esquerda. A pessoa 2 escolheu a mais à direita, que forçou a terceira a entrar no meio. Não é o número do mictório escolhido a seguir que deve ser produzido.
BrainSteel
4

Python 2, 208

n=input()
r=range(n)
l=[0]*n
def f(a,d=-1):
 if a>n:print''.join(l);return
 for i in r:
  t=min([n]+[abs(i-j)for j in r if l[j]])
  if t==d:p+=[i]
  if t>d:p=[i];d=t
 for i in p:l[i]=`a%10`;f(a+1);l[i]=0
f(1)

Abordagem recursiva.

Jakube
fonte
4

JavaScript (ES6) 153 160 169

Edite usando o Math.min para encontrar (é claro) a distância máxima: código simplificado e 16 bytes salvos.

Pesquisa recursiva, pode trabalhar com n> 10, basta remover% 10 (e esteja preparado para aguardar enquanto o console desenrola toda a sua saída).

Eu uso uma única matriz para armazenar o slot em uso (números positivos) ou a distância atual do slot mais próximo (números negativos <e >são trocados no código).

F=n=>{(R=(m,d,t,x=Math.min(...d=m?
  d.map((v,i)=>(c=i<t?i-t:t-i)?v<c?c:v:m%10)
  :Array(n).fill(-n)))=>
x<0?d.map((v,i)=>v>x||R(-~m,d,i)):console.log(d+[]))()}

Ungolfed

F=n=>{
  var R=(m, // current 'man', undefined at first step
   d, // slot array
   t // current position to fill
  ) =>
  {
    if (m) // if not at first step
    {
      d[t] = m % 10; // mark slot in use, (10 stored as 0 )
      d = d.map((v,i) => { // update distances in d[] 
        var c = i<t ? i-t : t-i; // distance from the current position (negated)
        return v < c ? c : v; // change if less than current distance
      });
    }
    else
    {
      d = Array(n).fill(-n) // fill distance array with max at first step
      // negative means slot free, value is the distance from nearest used slot
      // >= 0 means slot in use by man number 1..n 
    }
    var x = Math.min(...d);
    if ( x < 0 ) // if there is still any free slot
    {
      d.forEach((v,i) => { // check distance for each slot 
        if (v <= x) // if slot is at max distance, call recursive search
          R(-~m, [...d], i) // ~- is like '+1', but works on undefined too
      });
    }
    else
    {
      console.log(d+[]); // no free slot, output current solution
    }
  }

  R() // first step call
}

Teste no console Firefox / FireBug

F(5)

1,4,3,5,2
1,5,3,4,2
3,1,4,5,2
3,1,5,4,2
4,1,3,5,2
5,1,3 , 4,2
4,1,5,3,2
5,1,4,3,2
2,4,1,5,3
2,5,1,4,3
3,4,1,5,2
3 5,1,4,2
2,3,4,1,5
2,3,5,1,4
2,4,3,1,5
2,5,3,1,4
2,4,5, 1,3
2,5,4,1,3
2,4,3,5,1
2,5,3,4,1

edc65
fonte
2

Mathematica, 123 104

f[n_,s_:{}]:=If[Length@s<n,f[n,s~Join~{#}]&/@MaximalBy[Range@n,Min@Abs[#-s]&];,Print@@Ordering@s~Mod~10]
alefalpha
fonte
@ MartinBüttner n~f~s~Join~{#}se tornará Join[f[n,s],{#}].
Alephalpha
Ah, certo, eu pensei que era associativo.
Martin Ender
1

MATLAB, 164

function o=t(n),o=mod(r(zeros(1,n)),10);function o=r(s),o=[];d=bwdist(s);m=max(d);J=find(d==m);if~d,o=s;J=[];end,n=max(s)+1;for j=J,o=[o;r(s+n*(1:numel(s)==j))];end
knedlsepp
fonte
1

Perl, 174

Não é muito curto, mas divertido. Não estou contando use feature 'say';para o total de bytes.

$n=pop;@u="_"x$n." "x$n."_"x$n;for$p(1..$n){@u=map{my@r;for$x(reverse 0..$n){
s/(?<=\D{$x}) (?=\D{$x})/push@r,$_;substr $r[-1],pos,1,$p%10/eg and last;
}@r}@u}y/_//d&&say for@u

De-golfe:

$n = pop; # Get number of urinals from commandline
@state = ( "_" x $n . " " x $n . "_" x $n );

for my $person (1 .. $n) {
  # Replace each state with its list of possible next states.
  @state = map {
    my @results;
    for my $distance (reverse 0 .. $n) {
      # If there are any spots with at least $distance empty on
      # both sides, then add an entry to @results with the current
      # $person number in that spot, for each spot. Note that this
      # is only used for its side-effect on @results; the modified $_
      # is never used.
      s{
        (?<=\D{$distance})
        [ ]
        (?=\D{$distance})
      }{
        push @results, $_;
        substr $results[-1], pos(), 1, $person % 10;
      }xeg
      # If we found any spots, move on, otherwise try
      # with $distance one lower.
      and last;
    }
    # New state is the array we built up.
    @results;
  } @state;
}

# After adding all the people, remove underscores and print the results
for my $result (@state) {
  $result =~ tr/_//d;
  say $result;
}
hobbs
fonte
1

C, 248 bytes

Esse código usa um algoritmo recursivo para gerar o resultado desejado.

void q(char*f,int l,int d,char*o){char*c=f;while(f<c+l){if(!*f){sprintf(o+4*d,"%03i,",f-c);*f=1;q(c,l,d+1,o);*f=0;}f++;}if(d+1==l){o[4*d+3]=0;printf("%s\n",o);}}int main(int i,char**v){int k=atoi(v[1]);char*c=calloc(k,5),*o=c+k;q(c,k,0,o);free(c);}

Expandido:

void printperms(char* memory,int length,int offset,char*output)
{
    char*temp_char=memory;
    while(memory<temp_char+length)
    {
        if(!*memory)
        {
            sprintf(output+4*offset,"%03i,",memory-temp_char);
            *memory=1;
            printperms(temp_char,length,offset+1,output);
            *memory=0;
        }
        memory++;
    }
    if(offset+1==length)
    {
        output[4*offset+3]=0;
        printf("%s\n",output);
    }
}

int main(int i,char**v)
{
    int argument=atoi(v[1]);
    char*t=calloc(argument,5),*output=t+argument;
    printperms(t,argument,0,output);
    free(t);
}
Gerwin
fonte
1

Bash, 744 674 bytes

Ainda é muito longo :). Uso uma string para representar a fila de mictórios e um algoritmo de inundação para encontrar os mictórios mais distantes em cada fase da recursão. O código não destruído é quase autoexplicativo. O número de mictórios é lido no teclado.

Código (golfed):

read l;u=----------;u=-${u::$l}-
s(){ u=${u:0:$1}$2${u:$((1+$1))};}
m(){ local u=$1;a=();while :;do [ 0 -ne `expr index - ${u:1:$l}` ]||break;t=$u;y=$u;for i in `seq $l`;do [ ${y:$i:1} = - ]||{ s $(($i-1)) X;s $(($i+1)) X;};done;done;while :;do k=`expr index $t -`;[ 0 != $k ]||break;t=${t:0:$(($k-1))}X${t:$k};if [ 1 -ne $k ]&&[ $(($l+2)) -ne $k ];then a+=($(($k-1)));fi;done;}
e(){ local u f b v;u=$1;f=$2;if [ 1 -eq $l ];then echo 1;return;fi;if [ 1 = $f ];then for i in `seq $l`;do v=$u;s $i 1;e $u 2;u=$v;done;else m $u;b=(${a[@]});if [ 0 -eq ${#b} ];then echo ${u:1:$l};else for i in ${b[@]};do v=$u;s $i $(($f%10));e $u $(($f+1));u=$v;a=(${b[@]});done;fi;fi;}
e $u 1

Usar:

$ source ./script.sh
input number of urinals from keyboard

E não destruído, ele diz:

read l  # read number of urinals
u=----------
u=-${u:0:$l}- #row is two positions longer (it will be helpful when finding the most distant urinals)

# So, for the end, with 6 men, u might look like this:
# -143652-

# subu no fellow_no => set urinal [number] occupied by [fellow_no]
# this is just convenience for resetting a character inside a string
subu(){ u=${u:0:$1}$2${u:$((1+$1))};}


# this will be iterated in longest to find the remotest places:
# -1---3---2- => spreadstep => X1X-X3X-X2X => spreadstep => X1XXX3XXX2X
# see longest() to get more explanation.
spreadstep()
{
    y=$u
    for i in `seq 1 $l`
    do
    if [ "${y:$i:1}" != "-" ]
    then
        subu $(($i-1)) X
        subu $(($i+1)) X
    fi
    done
}

# Find the urinals with the longest distance. It uses spreadstep() - see above.
# -1---3---2- => spreadstep => X1X-X3X-X2X => spreadstep => X1XXX3XXX2X
# ---> last state with free ones was X1X-X3X-X2X ,
#                                     123456789
# free urinals are no. 3 and no. 7 => save them to arr
longest()
{
    local u=$1
    arr=()
    while true
    do
        if [ 0 -eq `expr index - ${u:1:$l}` ]
        then
            break
        fi
        save=$u
        spreadstep
    done

    while true
    do
        index=`expr index $save -`
        if [ 0 == $index ]
        then
            break
        fi

        save=${save:0:$(($index-1))}X${save:$index}
        if [ 1 -ne $index ] && [ $(($l+2)) -ne $index ]
        then
            arr+=($(($index-1)))
        fi
    done
}

# main function, recursively called
# the first fellow may take any of the urinals.
# the next fellows - only those with the longest distance.
placements_with_start()
{
    local u=$1
    local fellow=$2
    if [ 1 -eq $l ] # special case - there is no 2nd fellow, so below code would work incorrect 
    then
        echo "1"
        return
    fi
    if [ 1 == $fellow ]       # may take any of urinals
    then
        for i in `seq 1 $l`
        do
            local _u=$u
            subu $i 1                     # take the urinal
            placements_with_start $u 2    # let the 2nd fellow choose :)
            u=$_u
        done
    else
        longest $u   # find the ones he can take
        local _arr=(${arr[@]})
        if [ 0 -eq ${#_arr} ]
        then
            echo ${u:1:$l}    # no more free urinals - everyone took one - print the result
        else
            for i in ${_arr[@]}
            do
                local _u=$u
                subu $i $(($fellow % 10))                # take urinal
                placements_with_start $u $(($fellow+1))  # find locations for for next fellow
                u=$_u
                arr=(${_arr[@]})
            done
        fi
    fi
}

placements_with_start $u 1
pawel.boczarski
fonte