16
\$\begingroup\$

A string whose length is a positive triangular number (1, 3, 6, 10, 15...) can be arranged into an "equilateral text triangle" by adding some spaces and newlines (and keeping it in the same reading order).

For example, the length 10 string ABCDEFGHIJ becomes:

   A
  B C
 D E F
G H I J

Write a program or function that takes in such a string, except it will only contains the characters 0 and 1. (You may assume the input is valid.)

For the resulting "equilateral text triangle", output (print or return) one of four numbers that denotes the type of symmetry exhibited:

  • Output 2 if the triangle has bilateral symmetry. i.e. it has a line of symmetry from any one corner to the opposite side's midpoint.

    Examples:

     0
    1 1
    
     1
    0 1
    
      0
     0 1
    0 1 0
    
       1
      1 1
     1 0 1 
    0 1 1 1
    
  • Output 3 if the triangle has rotational symmetry. i.e. it could be rotated 120° with no visual change.

    Examples:

       0
      1 0
     0 1 1
    0 1 0 0
    
       0
      0 1
     1 0 0
    0 0 1 0
    
        1
       0 1
      1 1 1
     1 1 1 0
    1 0 1 1 1
    
         1
        0 1
       0 0 1
      1 0 0 0
     1 0 0 0 0
    1 0 0 1 1 1
    
  • Output 6 if the triangle has both bilateral and rotational symmetry. i.e. it matches the conditions for outputting both 2 and 3.

    Examples:

    0
    
    1
    
     0
    0 0
    
      1
     0 0
    1 0 1
    
       0
      0 0
     0 1 0
    0 0 0 0
    
  • Output 1 if the triangle has neither bilateral nor rotational symmetry.

    Examples:

      1
     1 0
    0 0 0
    
      0
     0 1
    1 0 1
    
       1
      1 0
     1 1 1 
    1 1 1 1
    
        1
       1 1
      1 1 1 
     0 0 0 1
    1 1 1 1 1
    

The shortest code in bytes wins. Tiebreaker is earlier answer.

Aside from an optional trailing newline, the input string may not have space/newline padding or structure - it should be plain 0's and 1's.

If desired you may use any two distinct printable ASCII characters in place of 0 and 1.

Test Cases

Taken direct from examples.

011 -> 2
101 -> 2
001010 -> 2
1111010111 -> 2
0100110100 -> 3
0011000010 -> 3
101111111010111 -> 3
101001100010000100111 -> 3
0 -> 6
1 -> 6
000 -> 6
100101 -> 6
0000100000 -> 6
110000 -> 1
001101 -> 1
1101111111 -> 1
111111000111111 -> 1

"Rotating" any input by 120° will of course result in the same output.

\$\endgroup\$
3
  • \$\begingroup\$ That title is just painful...... \$\endgroup\$
    – Riker
    Apr 27, 2016 at 15:28
  • 10
    \$\begingroup\$ @EᴀsᴛᴇʀʟʏIʀᴋ Just tri to ignore it. \$\endgroup\$ Apr 27, 2016 at 15:31
  • \$\begingroup\$ @HelkaHomba Why... why... \$\endgroup\$
    – clismique
    Jul 10, 2016 at 18:52

1 Answer 1

10
\$\begingroup\$

CJam, 37 29 28 27 bytes

Thanks to Sp3000 for saving 3 bytes.

q{T):T/(\s}h]{z_Wf%_}3*])e=

Test suite.

This reuses some triangle rotation tricks from this challenge.

This also works for the same byte count:

q{T):T/(\s}h]3{;z_Wf%_}%)e=

Explanation

First, a quick recap from the triangle post I linked to above. We represent a triangle as a 2D (ragged) list, e.g.

[[0 1 1]
 [0 0]
 [0]]

The symmetry group of the triangle has 6 elements. There are cycles of length 3 by rotating the triangle and cycles of 2 by mirroring it along some axis. Conveniently, the rotations correspond to perform to two different reflections. We will use the following reflections to do this:

  1. Transpose the list means reflecting it along the main diagonal, so we'd get:

    [[0 0 0]
     [1 0]
     [1]]
    
  2. Reversing each row represents a reflection which swaps the top two corners. Applying this to the result of the transposition we get:

    [[0 0 0]
     [0 1]
     [1]]
    

Using these two transformations, and keeping the intermediate result, we can generate all six symmetries of the input.

A further point of note is the behaviour of transposition on a list like this:

[[0]
 [1 0]
 [1 0 0]
 []]

Because that's what we'll end up with after splitting up the input. Conveniently, after transposing, CJam flushes all lines to the left, which means this actually gets rid of the extraneous [] and brings it into a form that's useful for the above two transformations (all without changing the actual layout of the triangle beyond reflectional symmetry):

[[0 1 1]
 [0 0]
 [0]]

With that out of the way, here's the code:

q       e# Read input.
{       e# While the input string isn't empty yet...
  T):T  e#   Increment T (initially 0) and store it back in T.
  /     e#   Split input into chunks of that size.
  (     e#   Pull off the first chunk.
  \s    e#   Swap with remaining chunks and join them back together
        e#   into a single string.
}h
]       e# The stack now has chunks of increasing length and an empty string
        e# as I mentioned above. Wrap all of that in an array.
{       e# Execute this block 3 times...
  z_    e#   Transpose and duplicate. Remember that on the first iteration
        e#   this gets us a triangle of the desired form and on subsequent
        e#   iterations it adds one additional symmetry to the stack.
  Wf%_  e#   Reverse each row and duplicate.
}3*
        e# The stack now has all 6 symmetries as well as a copy of the
        e# last symmetry.
]       e# Wrap all of them in a list.
)       e# Pull off the copy of the last symmetry.
e=      e# Count how often it appears in the list of symmetries.
\$\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.