Inteiros de pilha de areia

18

Desafio

Você receberá um número inteiro positivo ncomo entrada. A saída deve ser uma pilha de areia do tipo pirâmide, construída com base nas regras especificadas abaixo:

  • Cada número inteiro "cai" para baixo a partir do mesmo ponto inicial, como areia caindo em forma de conal.
  • Os números maiores que o número diretamente abaixo, quando atingem o monte de areia, cairão para a direita, se possível.
  • Os números inferiores ao número diretamente abaixo, quando atingir o monte de areia, cairão para a esquerda, se possível.
  • Números iguais ao número logo abaixo quando atingir o monte de areia permanecerão no lugar.
  • Os números podem cair para a esquerda / direita, se puderem se mover para baixo e para a esquerda / direita, respectivamente. Ou seja, se já houver um número abaixo e à esquerda / direita, dependendo da direção, o número atualmente em queda não se move.
  • Um número continuará caindo no monte de areia até que ele não possa ser movido para sua próxima posição ou atingir o chão.

Notas

A verificação de comparação inicial se aplica somente ao primeiro número inteiro encontrado, não a cada encontro sucessivo, uma vez que cai no monte de areia.

Os espaços à direita são bons, mas as novas linhas à direita não.

Não há espaços à esquerda ou novas linhas, exceto onde necessário para preservar a estrutura da pilha de areia.

Você pode escrever um programa ou função completo.

Você pode assumir que a entrada conterá apenas alguma combinação [0-9].

Isso é , o código mais curto em bytes será marcado como vencedor pelos dias de março

Exemplos

1

1


12345

35
124


54321

 13
245


555444333222111

    2
    2
    2
  135
 1345
13445


111222333444555

4
4
4
135
1235
12235


7313623030872935273465247457435345345350

    3
    3
    3
    3
    34
    355
    3644
   239475
  201277445
020373685575
CzarMatt
fonte
555444333222111é um erro que o terceiro 4caia da esquerda para o primeiro 4?
andlrc 23/02
Os números @ dev-null continuarão 'caindo', se você quiser, desde que eles sejam capazes - lembre-se, a verificação maior / menor / igual se aplica apenas ao primeiro encontro.
CzarMatt 23/02

Respostas:

4

JavaScript (ES6), 260 208 bytes

s=>[...s].map(c=>a[g(n,(c>(l=a[n].slice(-1)))-(c<l))]+=c,n=s.length,a=Array(n+n).fill(''),g=(i,d)=>a[i].length>a[i+d].length?g(i+d,d):n)&&[...a[n]].map((_,i)=>a.map(c=>c?c[i]||' ':c).join``).reverse().join`\n`

Editar: salvou 25 bytes ao perceber que o primeiro caractere não é um caso especial. Economizou 15 bytes usando uma matriz de seqüências de caracteres em vez de uma matriz de matrizes de caracteres. 12 bytes salvos em correções diversas, incluindo o uso de um literal \n(não mostrado). Isso torna todo esse 20% mais curto! Eu queria me livrar, reversemas isso custa mais do que posso economizar substituindo mappor replace.

Ungolfed:

function sandpile(str) {
    var arr = new Array(str.length * 2); // max width of sandpile is approx. 2√n but this is close enough
    for (i = 0; i < arr.length; i++) arr[i] = '';
    for (i = 0; i < str.length; i++) {
        var digit = str[i];
        var pos = str.length; // start dropping here
        if (digit < str[pos][str[pos].length - 1]) {
            while (str[pos - 1].length < str[pos].length) pos--;
        } else if (digit > str[pos][str[pos].length - 1]) {
            while (str[pos + 1].length < str[pos].length) pos++;
        }
        str[pos] += digit; // drop the digit
    }
    var len = arr[str.length].length; // final height
    // remove the unused columns, and then pad the columns with spaces for the transpose
    for (i = 0; i < arr.length; ) {
        if (!arr[i]) arr.splice(i, 1);
        else arr[i++] += ' '.repeat(len);
    }
    ans = '';
    for (i = len; i-- > 0; ) {
        for (j = 0; j < arr.length; j++) ans += arr[j][i];
        ans += '\n';
    }
    return ans;
}
Neil
fonte