25
\$\begingroup\$

See also: Rotatagons

Challenge

Given a string as input, output its wordagon.

Wordagons

A wordagon is a way of representing a string in a hexagon. Now, let's create a wordagon from the string hexa:

Firstly, you start with the first character in the string a place it in the centre:

h

Then, you take the next character in the string and add a hexagonal layer:

 e e
e h e
 e e

Then, add the next layer:

  x x x
 x e e x
x e h e x
 x e e x
  x x x

Finally, add the last layer:

   a a a a
  a x x x a
 a x e e x a
a x e h e x a
 a x e e x a
  a x x x a
   a a a a

And you now have the wordagon for the string hexa.

Examples

Here's some I prepared earlier:

hello

    o o o o o
   o l l l l o
  o l l l l l o
 o l l e e l l o
o l l e h e l l o
 o l l e e l l o
  o l l l l l o
   o l l l l o
    o o o o o

PPcg

   g g g g
  g c c c g
 g c P P c g
g c P P P c g
 g c P P c g
  g c c c g
   g g g g

o *

  * * *
 *     *
*   o   *
 *     *
  * * *

(T_T)

    ) ) ) ) )
   ) T T T T )
  ) T _ _ _ T )
 ) T _ T T _ T )
) T _ T ( T _ T )
 ) T _ T T _ T )
  ) T _ _ _ T )
   ) T T T T )
    ) ) ) ) )

Note that trailing and/or leading newlines are allowed.

Winning

The shortest code in bytes wins.

\$\endgroup\$
  • 14
    \$\begingroup\$ Bonus points if someone does this in Hexagony? ;) \$\endgroup\$ – Kevin Cruijssen Sep 5 '16 at 12:46
  • \$\begingroup\$ Can the input string contain linefeeds? I don't think it would pose any implementation problem, just produce invalid wordagons \$\endgroup\$ – Aaron Sep 5 '16 at 12:52
  • \$\begingroup\$ @Aaron No, the input string will never include newlines \$\endgroup\$ – Beta Decay Sep 5 '16 at 12:57
  • \$\begingroup\$ is it ok if the output is a string with newlines returned from a function? \$\endgroup\$ – Daniel Sep 6 '16 at 1:24
  • 2
    \$\begingroup\$ Aww. I'm disappointed because I read the title as "word-dragons"... \$\endgroup\$ – mbomb007 Sep 6 '16 at 21:47
1
\$\begingroup\$

Pyth - 29 bytes

j+_K.e+*kdjdjF+*bhk*L2>zhkztK

Test Suite.

\$\endgroup\$
19
\$\begingroup\$

Python 2, 83 bytes

s=input()
l=len(s)
while 1:l-=1;y=abs(l);print' '*y+' '.join(s[:y:-1]+s[y]*y+s[y:])

Prints the wordagon and then crashes (which only prints to STDERR).

Example:

% python2.7 wordagon.py <<<'"abcde"' 2&>/dev/null
    e e e e e
   e d d d d e
  e d c c c d e
 e d c b b c d e
e d c b a b c d e
 e d c b b c d e
  e d c c c d e
   e d d d d e
    e e e e e

xnor saved 5 bytes. Thanks!

\$\endgroup\$
  • 2
    \$\begingroup\$ Elegant solution. \$\endgroup\$ – DavidC Sep 5 '16 at 15:24
  • 1
    \$\begingroup\$ You can loop through the y's by doing n=len(s)\nwhile 1:n-=1;y=abs(n);... and terminating with error. \$\endgroup\$ – xnor Sep 5 '16 at 21:19
10
\$\begingroup\$

Vim, 92 bytes

:se ri|s/./ &/g
ⓋCⓇ"Ⓓ␛$vpmlmrqqYpi ␛`ljxxhmlylv`rjlmr:s/\%V\(.\)./Ⓡ" /g
@qq@qVdy2G:g/^/m0
Gp

Circled letters represent Control + letter; ␛ is escape.

asciicast

\$\endgroup\$
  • 3
    \$\begingroup\$ Wouldn't this be counted as keystrokes? \$\endgroup\$ – Soren Sep 5 '16 at 16:29
  • 1
    \$\begingroup\$ @moo_we_all_do No. This is code-golf (as opposed to editor golf), so all answers should be scored in bytes. \$\endgroup\$ – Martin Ender Sep 6 '16 at 6:25
  • \$\begingroup\$ The second @q causes an infinite loop for me. It works perfectly if it's removed. \$\endgroup\$ – MTCoster Sep 6 '16 at 9:51
6
\$\begingroup\$

Mathematica 100 219 bytes

If ASCII-Art need not be Terminal-Art this should be valid.

My earlier submission mistakenly drew a star rather than a hexagon. I can't see how I was so off!

c = CirclePoints@6;
f@s_:=Graphics[{Text[s~StringPart~1,{0,0}],Flatten@Table[Text[StringPart[s,n+1],#]&/@Subdivide[Sequence@@#,n]&/@Partition[Riffle[(n)CirclePoints@6,RotateLeft[n CirclePoints@6]],2],{n,1,StringLength@s-1}]},BaseStyle->20]

CirclePoints@6 returns the vertices of a unit hexagon, assuming that the center is at the origin.

Subdivideing the coordinates for neighboring vertices finds equally spaced positions along the respective edge.

A counter from 1 through the StringLength -1 of the input string allows each layer of the wordagon to be handled separately.
As n increases, so does the respective distance of each vertex from the origin.

Text[s~StringPart~1,{0,0}] prints the first letter of the input at the origin.


f@"Wordagon"

wordagon


For the curious, this is what the star version looked like. I know, it was way off the mark. It only showed the letters at the hexagon's vertices.

Graphics@Table[Text[Style[StringPart[#, r + 1], 54], r {Cos@t, Sin@t}], {t, 0, 2π, π/3}, {r, 0, StringLength@# - 1}] &["Hexa"]

hexa

\$\endgroup\$
  • 5
    \$\begingroup\$ Can you post what the star looked like? :D \$\endgroup\$ – Beta Decay Sep 5 '16 at 14:36
  • \$\begingroup\$ Sure. It's now posted. \$\endgroup\$ – DavidC Sep 5 '16 at 15:14
  • 2
    \$\begingroup\$ Wow, that is a nice star \$\endgroup\$ – Beta Decay Sep 5 '16 at 15:18
3
\$\begingroup\$

Ruby, 82 bytes

->s{n=s.size-1
(r=-n..n).map{|i|(" "*k=i.abs)+r.map{|j|s[[k+j,k,-j].max]}*" "}*$/}

iterates through 1-n..n-1 in both i=y and j=x directions. Without the leading spaces on each line, the output looks like the below, as a result of picking a character from s with the index [[i.abs+j,i.abs,-j].max]. Adding leading spaces forms the required hexagon.

f f f f
f l l l f
f l o o l f
f l o G o l f
f l o o l f
f l l l f
f f f f

Ungolfed in test program

f=->s{
  n=s.size-1             n=string length - 1
  (r=-n..n).map{|i|      iterate from -n to n, build an array of lines
    (" "*k=i.abs)+       k=i.abs. Start each line with k spaces.
    r.map{|j|            iterate from -n to n, build an array of characters.
      s[[k+j,k,-j].max]  select character from s (store null string in array if index past end of string)
    }*" "                concatenate the array of characters into a line, separated by spaces
  }*$/                   concatenate the array of lines into a single string, separate by newlines
}

puts f[gets.chomp]

Typical output

   f f f f
  f l l l f
 f l o o l f
f l o G o l f
 f l o o l f
  f l l l f
   f f f f
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 118 bytes

s=>[...Array((l=s.length-1)*2+1)].map((_,i,a)=>a.map((_,j)=>s[Math.max(i-l,l-i,j-l,i-j,l+l-i-j)]||``).join` `).join`\n`

Where \n represents the literal newline character. Based on my answer to Hexplosive ASCII-art challenge although parts of the solution resemble @LevelRiverSt's Ruby answer. The various components of the Math.max produce the following output for l=3:

    i - l           l - i           j - l            i - j        l + l - i - j
- - - - - - -   3 3 3 3 3 3 3   - - - 0 1 2 3    0 - - - - - -    6 5 4 3 2 1 0
- - - - - - -   2 2 2 2 2 2 2   - - - 0 1 2 3    1 0 - - - - -    5 4 3 2 1 0 -
- - - - - - -   1 1 1 1 1 1 1   - - - 0 1 2 3    2 1 0 - - - -    4 3 2 1 0 - -
0 0 0 0 0 0 0   0 0 0 0 0 0 0   - - - 0 1 2 3    3 2 1 0 - - -    3 2 1 0 - - -
1 1 1 1 1 1 1   - - - - - - -   - - - 0 1 2 3    4 3 2 1 0 - -    2 1 0 - - - -
2 2 2 2 2 2 2   - - - - - - -   - - - 0 1 2 3    5 4 3 2 1 0 -    1 0 - - - - -
3 3 3 3 3 3 3   - - - - - - -   - - - 0 1 2 3    6 5 4 3 2 1 0    0 - - - - - -

The maximum value is taken, and the values greater than l are removed, thus producing the hexagon shape, while the remaining values map to characters from the string:

6 5 4 3 3 3 3      3 3 3 3          a a a a
5 4 3 2 2 2 3     3 2 2 2 3        a x x x a
4 3 2 1 1 2 3    3 2 1 1 2 3      a x e e x a
3 2 1 0 1 2 3   3 2 1 0 1 2 3    a x e h e x a
4 3 2 1 1 2 3    3 2 1 1 2 3      a x e e x a
5 4 3 2 2 2 3     3 2 2 2 3        a x x x a
6 5 4 3 3 3 3      3 3 3 3          a a a a
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 31 bytes

R.pvy`¹gN-©×NFs.ø}Sðý®ð×ì})¦«»

Explanation

Utilizing symmetry to only generate the top part of the hexagon,
then mirroring that to form the lower part.

R.pv                     }       # for each prefix of the reversed string
                                 # ['f', 'fl', 'flo', 'floG']
    y`                           # split into chars, ex: 'f', 'l', 'o'
      ¹gN-©×                     # repeat the last char len(input)-N times, 
                                 # where N is the 0-based list index of the current prefix
                                 # ex: 'oo'
            NF   }               # N times do
              s.ø                # surround current char with the next char on stack
                                 # ex: 'floolf'
                  Sðý            # insert spaces between each letter, ex: 'f l o o l f'
                     ®ð×ì        # prefix string with len(input)-N spaces
                                 # ex: '  f l o o l f'
                          )      # wrap all strings in a list
                           ¦    # create a reversed copy of the list and 
                                 # remove the first item (as we only need the middle once)
                             «»  # concatenate the lists and merge with newlines

Try it online!

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

Python 2, 104 bytes

def f(s):
 for n in range(len(s)*2-1):x=abs(n-len(s)+1);print' '*x+' '.join(s[x+1:][::-1]+s[x]*x+s[x:])
\$\endgroup\$
0
\$\begingroup\$

PHP - 202 bytes

$w=$argv[1];$l=$i=$a=strlen($w)-1;while(-$l<=$i){$s=join(" ",str_split(str_repeat($w[$l],($a-1)/2).substr($w,$a?$a:1,$l+1),1));echo str_pad("",$a).strrev($s).($a%2?" ":" {$w[$a]} ")."$s
";$a=abs(--$i);}

Usage from command line:

php.exe -r "put the escaped code here" "put your desired word here"

for example:

php.exe -r "$w=$argv[1];$l=$i=$a=strlen($w)-1;while(-$l<=$i){$s=join(\" \",str_split(str_repeat($w[$l],($a-1)/2).substr($w,$a?$a:1,$l+1),1));echo str_pad(\"\",$a).strrev($s).($a%2?\" \":\" {$w[$a]} \").\"$s\n\";$a=abs(--$i);}" "example"

Test Suite.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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