11
\$\begingroup\$

Credit

My thanks to Rand Al'Thor's letter-based question for the inspiration for this code-golf challenge.

Background

The nature of this challenge is based off the algorithm mentioned by Rand in his "A Triangle Formed of Three Letters":

  • Start with a sequence of 10 letters each of which is X, Y, or Z.
  • Under each row, construct the next row as follows. If two adjacent letters are the same, write the same letter beneath them; if they're different, write the third letter beneath them.

You would then repeat the previous step until you have one letter in your tenth row.

Challenge

We're going to put a mathematical spin on the above algorithm:

  • Let's start with a sequences of 10 digits, each separated by a space, and each of which is either 1, 2 or 3.
  • Under each row, construct the next row as follows. If two adjacent digits are the same, write the same digit beneath them; if they're different, write the third digit beneath them.
  • Repeat the previous step until you have one final number.

So, following this algorithm, if starting with the row 1 2 3 3 1 3 1 3 1 2, for example, the following triangle is generated:

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         

I'm also curious to know the sum of all the digits in the number triangle, so add all these digits, and put this total in an eleventh row, right-justified to the last digit in the first row. So, our number triangle will look something like the following (spaces in my example are represented below by the . character to show formatting.)

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

Your challenge is to write code that can start with an inputted string/array/etc. of ten digits, as per my example, and then apply the algorithm to generate the ten rows that would create the number triangle, followed by an 11th row that would display the total of all digits with right-justification.

Testing

Testing of this string can be performed with a randomly generated string of ten digits of your choosing, or one generated from the snippet below...

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.

Rules

  1. Code-golf rules apply, so lowest number of bytes wins the challenge. In the event that there are two entries with the same low score, the winner will be awarded based on the number of up-votes.
  2. What we're basically after is 11 rows, 19 characters long... How you render your final output is entirely up to you: array, console, file output, STDOUT, etc., so please use whatever output method you like that will work to your advantage. The only rule in the output is that we have 11 rows with 19 characters in each row in a similar format to above...
  3. If it helps your code, use whatever separator for the digits... Just remember that legibility may be a contributing factor.
  4. No silly loopholes.
  5. Hard-coding of the input is not allowed. The purposes of this code is such that it can be used to produce different results each time with varying input. Hard-coding of 1 1 1 1 1 1 1 1 1 1 for example, completely negates the whole point of the algorithm.

Look forward to seeing what you all can come up with!

\$\endgroup\$
8
  • \$\begingroup\$ Sorta related \$\endgroup\$
    – DJMcMayhem
    Sep 26, 2016 at 0:24
  • 1
    \$\begingroup\$ Do I need a separator if my triangle is center-aligned (which is thus legible)? \$\endgroup\$ Sep 26, 2016 at 3:44
  • 1
    \$\begingroup\$ It looks like this without the space (my answer has space, which takes 10 bytes). \$\endgroup\$ Sep 26, 2016 at 3:55
  • 2
    \$\begingroup\$ Permission granted \$\endgroup\$ Sep 26, 2016 at 5:21
  • 1
    \$\begingroup\$ Note that for a string of 10 (or any number 1 greater than a power of 3) digits, the final digit is trivially calculated from the first and last digit in the string; the other digits make no difference. \$\endgroup\$
    – Neil
    Sep 26, 2016 at 13:42

8 Answers 8

7
\$\begingroup\$

Mathematica, 104 97 90 94 bytes

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

Explanation

Partition[#,2,1]

Partitions the input into length 2, offset 1 partitions.

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

Takes each partition, and calculates the corresponding output.

A trick involved here. I added up the two numbers, took mod 3, and subtracted that result from 3. That gives the desired number. (e.g. 3 - ((2 + 1) mod 3) = 3)

NestList[ ... ,9]

Repeats the above process nine times, giving all iterations as the output.

Grid[List@*Row/@#]

Format each iteration into rows, and put the entire thing in one column (center aligned), creating a triangle.

#~Total~2

Take the total of all numbers.

{...}~Column~Right

Combine the triangle and the total, and right align the entire thing (triangle is already aligned, so its alignment is not affected).

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Inspired approach with a single function that takes care of both the identical and different parent types... I like it! \$\endgroup\$ Sep 26, 2016 at 4:07
3
\$\begingroup\$

JavaScript (ES6), 143 142 bytes

Saved 1 byte thanks to @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)

I tried combining various parts, but it ended up 5 bytes longer:

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`
`
\$\endgroup\$
6
  • \$\begingroup\$ Great work! Could JHM's trick of 3-((x+y)%3) be of any help reducing this code? \$\endgroup\$ Sep 26, 2016 at 4:15
  • 2
    \$\begingroup\$ Nope. p^c||p is already quite a bit shorter :-) \$\endgroup\$ Sep 26, 2016 at 4:17
  • \$\begingroup\$ Now, how the hell did I miss that? Of course! XOR functions work well here! \$\endgroup\$ Sep 26, 2016 at 4:24
  • 1
    \$\begingroup\$ XOR?! I couldn't have thought of that. That being said, sadly, using XOR makes my code longer :P \$\endgroup\$ Sep 26, 2016 at 5:13
  • \$\begingroup\$ For i?p^(p=c)||p:c can you use i&&p^(p=c)||c? \$\endgroup\$
    – Neil
    Sep 26, 2016 at 13:50
2
\$\begingroup\$

Ruby, 134 101 bytes

Using JHM's modulo trick.

->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(:+)}

See it on eval.in: https://eval.in/649993

\$\endgroup\$
2
\$\begingroup\$

CJam,  44  40 bytes

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

Try it online!

Explanation

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.
\$\endgroup\$
4
  • \$\begingroup\$ As always, very impressive! You're in the lead so far! \$\endgroup\$ Sep 26, 2016 at 7:53
  • 1
    \$\begingroup\$ @WallyWest Thanks. :) Just wait Pyth, Jelly and MATL. ;) \$\endgroup\$ Sep 26, 2016 at 7:54
  • \$\begingroup\$ Actually, I'm curious to know what the GolfScript solution will look like... ;) \$\endgroup\$ Sep 26, 2016 at 7:58
  • \$\begingroup\$ Oh, anyone up to posting an SQL solution? ;) \$\endgroup\$ Sep 26, 2016 at 7:59
1
\$\begingroup\$

05AB1E, 32 26 bytes

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

Explanation

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Python 2, 164 bytes

A relatively simple iterative solution.

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

Try it online

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 112 100 96 bytes

Takes an array as input and recursively builds a comma-separated triangle.

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)

\$\endgroup\$
0
1
\$\begingroup\$

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);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.