Triângulos numéricos


11

Crédito

Meus agradecimentos à pergunta baseada em cartas de Rand Al'Thor pela inspiração para este desafio do código-golfe.

fundo

A natureza desse desafio é baseada no algoritmo mencionado por Rand em "Um triângulo formado por três letras":

  • Comece com uma sequência de 10 letras, cada uma das quais é X, Y ou Z.
  • Sob cada linha, construa a próxima linha da seguinte maneira. Se duas letras adjacentes forem iguais, escreva a mesma letra abaixo delas; se forem diferentes, escreva a terceira letra abaixo deles.

Você repetiria a etapa anterior até ter uma letra na sua décima linha.

Desafio

Vamos colocar um giro matemático no algoritmo acima:

  • Vamos começar com uma sequência de 10 dígitos, cada um separado por um espaço, e cada um dos quais é 1, 2 ou 3.
  • Sob cada linha, construa a próxima linha da seguinte maneira. Se dois dígitos adjacentes forem iguais, escreva o mesmo dígito abaixo deles; se forem diferentes, escreva o terceiro dígito abaixo deles.
  • Repita a etapa anterior até ter um número final.

Portanto, seguindo este algoritmo, se começar com a linha 1 2 3 3 1 3 1 3 1 2, por exemplo, o seguinte triângulo é gerado:

Input: 1 2 3 3 1 3 1 3 1 2

Output:

1 2 3 3 1 3 1 3 1 2
 3 1 3 2 2 2 2 2 3 
  2 2 1 2 2 2 2 1  
   2 3 3 2 2 2 3   
    1 3 1 2 2 1    
     2 2 3 2 3     
      2 1 1 1      
       3 1 1       
        2 1        
         3         

Também estou curioso para saber a soma de todos os dígitos no triângulo numérico, portanto, adicione todos esses dígitos e coloque esse total na décima primeira linha, justificada à direita para o último dígito na primeira linha. Portanto, nosso triângulo numérico será parecido com o seguinte (espaços no meu exemplo são representados abaixo pelo .caractere para mostrar a formatação).

Input: 1 2 3 3 1 3 1 3 1 2

Output:

1.2.3.3.1.3.1.3.1.2
.3.1.3.2.2.2.2.2.3.
..2.2.1.2.2.2.2.1..
...2.3.3.2.2.2.3...
....1.3.1.2.2.1....
.....2.2.3.2.3.....
......2.1.1.1......
.......3.1.1.......
........2.1........
.........3.........
................109

Seu desafio é escrever um código que possa começar com uma string / array / etc. de dez dígitos, como no meu exemplo, e aplique o algoritmo para gerar as dez linhas que criariam o triângulo numérico, seguidas por uma 11ª linha que exibirá o total de todos os dígitos com justificativa à direita.

Teste

O teste dessa string pode ser realizado com uma string gerada aleatoriamente com dez dígitos de sua escolha ou um gerado a partir do snippet abaixo ...

c1=()=>('1331123221'+(Math.random()*(1<<24)|0).toString(4)).replace(/0/g, "").slice(-10).split("").join(" ");

$("#btn").click(function(){
  $("#str").val(c1());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="str"><button id="btn">Get numbers</button>
<br>
Please use this snippet to generate a starting row for testing your code. Alternatively, you can also use a string of your choice, so long as it's ten digits (ranging from 1 to 3), separated by single spaces.

Regras

  1. Aplicam-se as regras de código-golfe, portanto, o menor número de bytes vence o desafio. No caso de haver duas inscrições com a mesma pontuação baixa, o vencedor será premiado com base no número de votos positivos.
  2. Basicamente, procuramos 11 linhas, 19 caracteres ... Como você renderiza sua saída final: depende de você: matriz, console, saída de arquivo, STDOUT etc., portanto, use o método de saída que desejar. trabalhe a seu favor. A única regra na saída é que temos 11 linhas com 19 caracteres em cada linha em um formato semelhante ao anterior ...
  3. Se isso ajudar o seu código, use qualquer separador para os dígitos ... Lembre-se de que a legibilidade pode ser um fator que contribui.
  4. Sem brechas tolas .
  5. A codificação embutida da entrada não é permitida. Os propósitos deste código são tais que podem ser usados ​​para produzir resultados diferentes a cada vez, com entradas variáveis. A codificação embutida, 1 1 1 1 1 1 1 1 1 1por exemplo, nega completamente todo o ponto do algoritmo.

Ansiosos para ver o que todos vocês podem inventar!



1
Preciso de um separador se meu triângulo estiver alinhado ao centro (o que é legível)?
JungHwan Min 26/09/16

1
Parece que isso sem espaço (minha resposta tem espaço, que leva 10 bytes).
JungHwan Min 26/09/16

2
Permissão concedida
WallyWest 26/09/16

1
Observe que, para uma sequência de 10 (ou qualquer número 1 maior que uma potência de 3) dígitos, o dígito final é calculado trivialmente a partir do primeiro e do último dígito na sequência; os outros dígitos não fazem diferença.
Neil

Respostas:


1

05AB1E , 32 26 bytes

DvÐOˆðýðN×.ø,ü+3%3^}\¯O19j

Explicação

D                 # duplicate input
v                 # for y,N in input,len(input): (10 times do)
 Ð                # triplicate current list
 Oˆ               # sum one copy and add it to global array
 ðý               # merge one copy on spaces
   ðN×.ø          # surround it with N spaces
        ,         # and print it
 ü+               # reduce one copy by addition
   3%             # modulus 3
     3^           # XOR 3
                  # this is the list sent to the next iteration
}                 # end loop
\                 # drop empty list left over from last iteration of loop
 ¯O               # sum the global array giving the triangles total sum
   19j            # join with spaces up to 19 chars

Experimente online!


7

Mathematica, 104 97 90 94 bytes

{Grid[List@*Row/@#],#~Total~2}~Column~Right&[NestList[3-Mod[+##,3]&@@@Partition[#,2,1]&,#,9]]&

Explicação

Partition[#,2,1]

Particiona a entrada no comprimento 2, desloca 1 partições.

3-Mod[+##,3]&@@@

Toma cada partição e calcula a saída correspondente.

Um truque envolvido aqui. Acrescentei os dois números, peguei o mod 3 e subtraí o resultado de 3. Isso fornece o número desejado. (por exemplo, 3 - ((2 + 1) mod 3) = 3)

NestList[ ... ,9]

Repete o processo acima nove vezes, fornecendo todas as iterações como saída.

Grid[List@*Row/@#]

Formate cada iteração em linhas e coloque a coisa inteira em uma coluna (alinhada ao centro), criando um triângulo.

#~Total~2

Pegue o total de todos os números.

{...}~Column~Right

Combine o triângulo e o total e alinhe à direita a coisa toda (o triângulo já está alinhado, para que seu alinhamento não seja afetado).


1
Abordagem inspirada com uma única função que cuida dos tipos de pai idênticos e diferentes ... Eu gosto!
WallyWest 26/09/16

3

JavaScript (ES6), 143 142 bytes

Guardado 1 byte graças a @Neil

a=>a.map((_,i)=>(q=" ".repeat(i))+(a=a.map(c=>(x+=r=i&&p^(p=c)||c,r),p=i&&a.shift())).join` `+q,x=0).join`
`+`
`+(" ".repeat(18)+x).slice(-19)

Tentei combinar várias partes, mas acabou 5 bytes mais:

a=>[...a.map((_,i)=>(a=a.map(c=>(x+=r=i&&p^(p=c)||c,r),p=i&&a.shift())).join` `+" ".repeat(i),x=0),x].map(q=>(" ".repeat(18)+q).slice(-19)).join`
`

Ótimo trabalho! O truque da JHM pode 3-((x+y)%3)ajudar a reduzir esse código?
WallyWest 26/09/16

2
Não. p^c||pjá é um pouco mais curto :-)
ETHproductions

Agora, como diabos eu senti falta disso? Claro! As funções XOR funcionam bem aqui!
WallyWest 26/09/16

1
XOR ?! Eu não poderia ter pensado nisso. Dito isto, infelizmente, usar XOR torna meu código mais longo: P
JungHwan Min 26/09/16

Para i?p^(p=c)||p:cvocê pode usar i&&p^(p=c)||c?
Neil

2

Ruby, 134 101 bytes

Usando o truque de módulo da JHM.

->a{b=*a
(0..8).map{|i|[" "*i,a=a.each_cons(2).map{|x,y|b<<n=3-(x+y)%3
n}]*" "}<<"%19d"%b.reduce(:+)}

Veja-o em eval.in: https://eval.in/649993


2

CJam ,  44  40 bytes

l~{S*\_S*\2ew{:+3%3^}%2$N@}A%_s:~:+sJSe[

Experimente online!

Explicação

l~       e# Read and evaluate input.
{        e# Map this block over i in the range [0 1 ... 9].
  S*     e#   Get a string of i spaces (the indentation).
  \_     e#   Swap with the current line of trits and duplicate it.
  S*     e#   Join the trits with spaces.
  \2ew   e#   Swap with the other copy of the trits and get all consecutive pairs.
  {      e#   Map this block over the pairs...
    :+   e#     Sum the pair.
    3%   e#     Modulo 3.
    3^   e#     XOR 3.
         e#     This expression (x+y)%3 ^ 3 computes the required mapping.
  }%     e#   Now this is the next line.
  2$     e#   Copy the indentation (to pad the lines to equal length).
  N      e#   Push a linefeed.
  @      e#   Pull up the next line.
}A%      e# The result of this is a nested array whose string representation is
         e# the required triangle.
_s       e# Duplicate and flatten into a string.
:~       e# Eval each character which gives a list of all the trits.
:+       e# Sum that.
s        e# Turn the sum into a string.
JSe[     e# Left-pad it with spaces to width 19.

Como sempre, muito impressionante! Você está na liderança até agora!
WallyWest 26/09/16

1
@WallyWest Thanks. :) Apenas espere Pyth, Jelly e MATL. ;)
Martin Enders

Na verdade, estou curioso para saber o que a solução GolfScript será semelhante ...;)
Wally West

Ah, alguém quer postar uma solução SQL? ;)
WallyWest 26/09/16

1

Python 2, 164 bytes

Uma solução iterativa relativamente simples.

L=input()
s=0
for i in range(len(L)):
    print" "*-~i+" ".join(`L`[1::3]);s+=sum(L);N=L;L=[]
    for a,b in zip(N,N[1:]):L+=[list({1,2,3}-{a,b}),[a]][a==b]
print"%19s"%s

Experimente online


1

PHP, 143 bytes

<?for($t=$_GET[t];$i<181;$s+=$v,$i+=2)$t[$i+20]=($v=$t[$i])*($z=$t[$i+2])>0&$i!=18?($v+$z)%3^3:" ";echo chunk_split($t.str_pad($s,8," ",0),19);

0

JavaScript (ES6), 112 100 96 bytes

Toma uma matriz como entrada e cria recursivamente um triângulo separado por vírgula.

f=(s,p=`
`,S=0)=>p+(s[0]?s+f(s.map((v,i)=>(S+=v,v^s[i-1]||v)).slice(1),p+' ',S):(p+S).slice(-9))

console.log(f([1,2,3,3,1,3,1,3,1,2])); // reference example
console.log(f([3,3,2,1,3,1,2,1,2,1])); // random example
console.log(f([1,1,1,1,1,1,1,1,1,1])); // all ones (test case for sum < 100)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.