Making octogonal words

14

0

Last Thursday user @SpookyGengar delighted us with his/her first challenge about Making Squared Words. What if we double the number of sides?

The challenge

Take a string as input in any reasonable format you need (string, char array...) and output an octogonal representation of the input (also in any reasonable format: string, list of strings, char matrix...) as in the next examples:

Input: golf
Output:

   golf
  o    l
 l      o
f        g
l        o
o        l
g        f
 o      l
  l    o
   flog


Input: HelloWorld
Output:

         HelloWorld
        e          l
       l            r
      l              o
     o                W
    W                  o
   o                    l
  r                      l
 l                        e
d                          H
l                          e
r                          l
o                          l
W                          o
o                          W
l                          o
l                          r
e                          l
H                          d
 e                        l
  l                      r
   l                    o
    o                  W
     W                o
      o              l
       r            l
        l          e
         dlroWolleH


Input: a
Output:

a


Input: ab
Output:

 ab
b  a
a  b
 ba


Input: code golf
Output:

        code golf
       o         l
      d           o
     e             g

   g                 e
  o                   d
 l                     o
f                       c
l                       o
o                       d
g                       e

e                       g
d                       o
o                       l
c                       f
 o                     l
  d                   o
   e                 g

     g             e
      o           d
       l         o
        flog edoc

Notes

  • Input will consist only of printable ASCII characters.
  • Leading and/or trailing whitespaces and newlines allowed as long as the octogonal shape is maintained.
  • This is , so may the sortest program/function for each language win!

Charlie

Posted 2017-07-24T06:26:09.380

Reputation: 11 448

5"What if we double the number of sides?" <-- then charcoal would still win – Leaky Nun – 2017-07-24T06:30:55.803

Suggested testcase: code golf – Leaky Nun – 2017-07-24T06:31:46.360

@LeakyNun is <Space> considered printable? – V. Courtois – 2017-07-24T06:43:28.220

2

@V.Courtois yes

– Leaky Nun – 2017-07-24T06:44:32.027

@LeakyNun added test case. – Charlie – 2017-07-24T07:29:39.453

Answers

10

Charcoal, 16 bytes (10 bytes noncompeting)

F⁸«✂θ⁰±¹↷¹A⮌θθ»θ

Try it online! Link is to verbose version of code. Explanation:

F⁸«                 Repeat for each side of the octagon
   ✂θ⁰±    ¹        Print the input except the last character
        ↷¹          Rotate 45° clockwise
          A⮌θθ      Reverse the input string
              »θ    Print the input again, to handle the length 1 case

Alternative length 1 fix, also 16 bytes: Verbose version.

PθF⁸«✂θ⁰±¹↷¹A⮌θθ

A Charcoal bugfix means that the following 10-byte code now works: Verbose version.

F⁴«θ←↘⮌θ↖⟲

Neil

Posted 2017-07-24T06:26:09.380

Reputation: 95 035

seems like it should just do this. Lol – Magic Octopus Urn – 2017-07-24T14:39:45.593

1Umm, I don't think code golf works does it? – Erik the Outgolfer – 2017-07-24T15:17:05.750

Oh, and this is in fact 16 bytes (replace θθθ with θθ»θ). – Erik the Outgolfer – 2017-07-24T15:26:31.023

@EriktheOutgolfer Oops, sorry about that, I didn't think to test my fix for the length 1 case... my test record on the question hasn't been very good has it? – Neil – 2017-07-24T15:53:56.370

@Neil But what about the issue with code golf? I think that has to do with how Charcoal takes input, which, unfortunately, disqualifies it completely from this challenge as that can't be circumvented. – Erik the Outgolfer – 2017-07-24T15:55:24.447

@EriktheOutgolfer I think it's because of the way TIO passes input to Charcoal; if you add a newline you get a different result. – Neil – 2017-07-24T16:02:23.117

@Neil TIO doesn't explicitly add trailing stuff to the input, I think Charcoal uses something like .split() for input where if there's only one line it splits on spaces while if it's over multiple lines it splits on newlines. – Erik the Outgolfer – 2017-07-24T16:04:07.160

@EriktheOutgolfer Well since Charcoal can take input as a Python array it can be circumvented

– ASCII-only – 2017-07-26T00:20:49.440

@Neil Invited you as a collaborator if you want to/don't mind fixing bugs (I can explain how it works in chat or something), also even if you don't accept would you mind opening issues? Thanks in advance – ASCII-only – 2017-07-26T00:55:18.217

@Neil It isn't exactly the way TIO passes input, rather it's the way Charcoal parses input (python eval -> split by newline -> split by space, using the first one that works) – ASCII-only – 2017-07-26T00:56:08.387

Also verbose of the second one

– ASCII-only – 2017-07-26T01:05:02.123

Finally fixed the bug (theoretical one) (sorry) – ASCII-only – 2017-07-26T01:50:23.077

@ASCII-only Actually I'd since golfed the second one down so that it doesn't trigger the verbose bug, sorry about that. The original code was θ←↘⮌θ↖↓θ⟲OO↙²⁴⁶Lθ which can't be written in Verbose mode. – Neil – 2017-07-26T07:37:34.327

@ASCII-only Wow that means I can even have input with newlines! – Erik the Outgolfer – 2017-07-26T08:55:17.770

@Neil Oh, yeah I fixed that, so that's what you were talking about haha – ASCII-only – 2017-07-26T21:51:18.513

5

JavaScript (ES6), 156 bytes

f=
s=>[...Array((l=s.length-1)*3+1)].map((_,i,a)=>a.map((_,j)=>s[i+j-l?l*5-i-j?i+l*2-j?j+l*2-i?i%(l*3)?j%(l*3)?-1:j?i-l:l+l-i:i?l+l-j:j-l:j:l-i:l*3-i:i]||` `))
<input oninput=o.textContent=this.value?f(this.value).map(function(a){return(a.join``)}).join`\n`:``><pre id=o>

Returns a character array.

Neil

Posted 2017-07-24T06:26:09.380

Reputation: 95 035

1It seems to work only with strings of length 4. – Charlie – 2017-07-24T09:47:42.270

1@CarlosAlejo Sorry, didn't check carefully enough. Conveniently, fix saved 2 bytes! – Neil – 2017-07-24T11:42:26.193

Oh my that's a lot of ternary ?:s! – Erik the Outgolfer – 2017-07-24T14:59:30.830

@EriktheOutgolfer good thing it's not python or that would be really verbose :P – Stephen – 2017-07-24T15:11:50.463

3

Mathematica, 247 bytes

(T=Table;k=Length[s=Characters@#];If[k==1,#,Column[Flatten@{#,T[""<>{s[[i]],T["  ",k/2-2+i],s[[-i]]},{i,2,k}],T[""<>{s[[-i]],T["  ",k+k/2-2],s[[i]]},{i,2,k}],T[""<>{s[[i]],T["  ",3k/2-1-i],s[[-i]]},{i,2,k-1}],StringReverse@#},Alignment->Center]])&

J42161217

Posted 2017-07-24T06:26:09.380

Reputation: 15 931

You don't need Alignment and you'd save bytes by using delayedset (:=) to reduce the repetition of s[[i]] and s[[-i]], You get down to 224 bytes with these ideas: (T=Table;q:=s[[i]];r:=s[[-i]];k=Length[s=Characters@#];If[k==1,#,Column[Flatten@{#,T[""<>{q,T[" ",k/2-2+i],r},{i,2,k}],T[""<>{r,T[" ",k+k/2-2],q},{i,2,k}],T[""<>{q,T[" ",3k/2-1-i],r},{i,2,k-1}],StringReverse@#},Center]])& Also, I have an alternate solution that's only 145 bytes at the time of this comment.

– Mark S. – 2017-07-26T10:44:44.827

2

Pyth, 79 69 65 bytes

j++K+]+*dJtlzzm+++*;-Jd@zd*;+ytdlz@z_hdSJjL*;t*3tlztC_B_zt__MC.tK

Test suite.

Leaky Nun

Posted 2017-07-24T06:26:09.380

Reputation: 45 011

2

Japt, 84 79 bytes

-5 bytes thanks to @ETHproductions.


Ål
VoA{A?(UÅw +Uê)£Y¥V*2+AªY¥V-A?X:SÃ:Vç +U+Vç
Wf cU¬£V?(V*3 ç hUg~Y)+X:XÃcWz2

Leading newline is part of program. Takes a string as input and returns an array of strings.

Try it online! with the -R flag to join the resulting array with newlines.

Not my proudest work, but I got it down from ~100 bytes, at least. My idea here was to create the top and middle parts, then append the top portion, rotated 180°.

Justin Mariner

Posted 2017-07-24T06:26:09.380

Reputation: 4 746

Nice. I don't see a lot of improvements right away, but you could change Ul É to UÅl, and switch V and W to save 2 more bytes: https://codepen.io/justinm53/full/NvKjZr?code=CsVsClZvQXtBPyhVxXcgK1XqKaNZpVYqMitBqlmlQW5WID9YOlPDOlbnICtVK1bnCldmIGNVcSCjVj8oViozIOcgaFVnflkpK1g6WMNjV3oy&inputs=ImdvbGYi,IkhlbGxvV29ybGQi,ImEi,ImFiIg==,ImNvZGUgZ29sZiI=&flags=LVI=

– ETHproductions – 2017-07-25T14:09:30.957

Also, AnV ? -> V-A?, and Uq £ -> U¬£ – ETHproductions – 2017-07-25T14:11:35.850

@ETHproductions Awesome, thanks! Can't believe I forgot about ¬. – Justin Mariner – 2017-07-25T18:03:04.837

1

Python 2, 220 213 bytes

  • Surprisingly longer than I had imagined.
a=input()
l=len(a)
r=range(l)
print'\n'.join(p.center(l*3-2)for p in[a]+(l>1)*([a[i]+(2*i-2+l)*' '+a[~i]for i in r[1:-1]]+[a[~i]+(l*3-4)*' '+a[i]for i in r]+[a[i]+(3*l-2*i-4)*' '+a[~i]for i in r[1:-1]]+[a[::-1]]))

Try it online!

officialaimm

Posted 2017-07-24T06:26:09.380

Reputation: 2 739

1

Mathematica, 168 166 147 127 bytes

(n=Length@#;b=Array[" "&,3{n,n}-2];Do[l={{1,n+k-1},{k,n-k+1}};l=Join[l,Cross/@l];b=ReplacePart[b,Join[l,-l]->#[[k]]],{k,n}];b)&

This takes a list of one-character strings and outputs a matrix of one-character strings.

I saved 18 bytes by exploiting the symmetry to use -l and Cross/@l which takes something like a cross-product of each of the two single 2D vectors to take {x,y} to {-y,x}. Basically, the two initial directions are East (top edge) and Southwest (top right edge). Then we add in 90-degree counterclockwise rotations of them with Cross: North for left edge and Southeast for bottom left edge. Then we add in the other four pieces using -l to flip the four we covered.

You can test it out on the sandbox with something like:

(n=Length@#;b=Array[" "&,3{n,n}-2];Do[l={{1,n+k-1},{k,n-k+1}};l=Join[l,Cross/@l];b=ReplacePart[b,Join[l,-l]->#[[k]]],{k,n}];b)&[{"H","e","l","l","o"," ","G","o","l","f"}]//MatrixForm

Mark S.

Posted 2017-07-24T06:26:09.380

Reputation: 251

1

PHP 7.1, 230 156 155 bytes

for($x=$e=strlen($s=$argn)-1;$n<9;$r[$y][$x+=$n+1&3?$n&4?-1:1:0]=$s[$i],$i+=($n+=!$i||$i==$e)&1?:-1)$r[$y+=$n-1&3?$n<6?:-1:0]=$r[$y]?:"";echo join("
",$r);

Run as pipe with -nR or try it online.

breakdown

for($x=$e=strlen($s=$argn)-1;   # import to $s, set $e to length-1, init $x
    $n<9;                       # loop through 8 repetitions of string
    $r[$y][
        $x+=$n+1&3?$n&4?-1:1:0      # 3. increment/decrement $x depending on $n
    ]=$s[$i],                       # 4. copy character to current position
    $i+=(
        $n+=!$i||$i==$e             # 5. if first or last character of string, increment $n
    )&1?:-1                         # 6. if odd repetition next, else previous character
)
    $r[
        $y+=$n-1&3?$n<6?:-1:0       # 1. increment/decrement $y depending on $n
    ]=$r[$y]?:"";                   # 2. if empty, init row to string
echo join("\n",$r);             # output

Titus

Posted 2017-07-24T06:26:09.380

Reputation: 13 814