22
\$\begingroup\$

In the burial place of King Silo of Asturias there is an inscription that reads SILO PRINCEPS FECIT (King Silo made this).

SILO PRINCEPS FECIT

The first letter is found in the very middle, and from there one reads by going in any non-diagonal direction radiating outward. The final letter is found on all four corners. In this challenge, you'll generalize the process to make them.

Input

A string (or equivalent), and an integer. You may make the following assumptions about the input:

  • The string will have an odd length.
  • The integer will be an odd number between 1 and one less than twice the length of the string.

Output

An inscriptio labyrinthica for the string, using the integer for the height or width (see models for height examples). Output should be each letter with no spaces, line break as default to your system/language.

Test cases

Note that an input of 1 or (length * 2 - 1) will result in a horizontal or vertical palindrome.

 Input: FOO, 3    Input: BAR, 1    Input: BAR, 3    Input: BAR, 5

Output: OOO      Output: RABAR    Output: RAR       Output: R
        OFO                               ABA               A
        OOO                               RAR               B
                                                            A
                                                            R

 Input: ABCDE, 5   Input: ABCDE, 3   Input: *<>v^, 5

Output: EDCDE     Output: EDCBCDE           ^v>v^
        DCBCD             DCBABCD           v><>v
        CBABC             EDCBCDE           ><*<>
        DCBCD                               v><>v
        EDCDE                               ^v>v^

Scoring

This is so shortest answer in bytes wins. Standard loopholes forbidden.

\$\endgroup\$
  • 2
    \$\begingroup\$ not totally unrelated \$\endgroup\$ – Giuseppe Jul 18 at 17:45
  • \$\begingroup\$ Can the input contain spaces? If so, how should they be handled? \$\endgroup\$ – Nitrodon Jul 18 at 18:09
  • 1
    \$\begingroup\$ May we take input as a list of characters? \$\endgroup\$ – Robin Ryder Jul 18 at 19:36
  • 1
    \$\begingroup\$ @Charlie clearly you've been missing all my Perl6 answers :-) I expect an answer from you too since it's inspired by the fifth king of Spain (well, of Asturies, but Asturies ye España, y tolo demás ye tierra conquistao haha) \$\endgroup\$ – user0721090601 Jul 18 at 23:13
  • 1
    \$\begingroup\$ May we take the width instead of the height? \$\endgroup\$ – attinat Jul 19 at 4:18

17 Answers 17

6
\$\begingroup\$

J, 27 bytes

([{~]+/&(|@i:)#@[-1+])-:@<:

Try it online!

An example will clarify the high-level approach.

Consider 'ABCDE' f 3

We notice that what we seek is simply the "cross addition" table of 1 0 1 and 3 2 1 0 1 2 3, which looks like this:

4 3 2 1 2 3 4
3 2 1 0 1 2 3
4 3 2 1 2 3 4

We then pull those indexes from the original string: [{~.

All the rest of the code is just boring arithmetic and the use of i: to construct the arguments 1 0 1 and 3 2 1 0 1 2 3.

\$\endgroup\$
6
\$\begingroup\$

Jelly, 12 bytes

Uṡṛ‘HɗŒBŒḄZY

Try it online!

A dyadic link taking the string as its left and height as its right argument. Returns a string with line breaks. If a list of strings were acceptable for output, I can remove the final Y saving a byte. Interestingly the original “SILO PRINCEPS FECIT” looks to me like ASCII art of a 3D diamond when I look at it on TIO.

Explanation

U            | Reverse input
 ṡ   ɗ       | All overlapping substrings of the length given by:
  ṛ          | - The right argument
   ‘         | - Incremented by 1
    H        | - Halved
      ŒB     | Concatenate to the reverse, keeping a single copy of the last character (so creating a palindrome)
        ŒḄ   | Do the same, but this time using the lists of characters generated by the last atom
          Z  | Transpose
           Y | Join with newlines
\$\endgroup\$
  • 2
    \$\begingroup\$ I clicked on the try it just to see and yes, indeed, it does 3D. Weird but cool. \$\endgroup\$ – user0721090601 Jul 18 at 21:57
6
\$\begingroup\$

R, 93 91 87 bytes

-2 bytes thanks to Giuseppe. -4 bytes by inputting the width rather than the height, as allowed by OP.

function(s,W,w=W%/%2,h=length(s)-w-1)write(s[1+outer(abs(-w:w),abs(-h:h),`+`)],1,W,,"")

Try it online!

Takes input as a vector of characters. The key part is s[1+outer(abs(-w:w),abs(-h:h),'+')].

First compute \$w\$ and \$h\$ such that the output is of size \$(2w+1)\times(2h+1)\$.

In the output, we want the character in position \$(i,j)\$ to be the character at index \$1+|i-h|+|j-w|\$ in the input. This corresponds to the outer sum of abs(-w:w) and abs(-h:h) (abs(-h:h) is a short way of writing the vector \$[h, h-1, h-2, \ldots, 2, 1, 0, 1, 2, \ldots, h-1, h]\$). For instance, outer(abs(-2:2), abs(-1:1), '+') gives

32123
21012
32123

(we then need to add 1 because R is 1-indexed.) The 0 in the centre is where the first letter of the input should go.

The rest is formatting.

\$\endgroup\$
5
\$\begingroup\$

Charcoal, 25 19 bytes

E⊘⊕η✂θι⁺ι⁻Lθ⊘⊖η‖O←↑

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

E⊘⊕η✂θι⁺ι⁻Lθ⊘⊖η

Draw a quarter of the inscription.

‖O←↑

Reflect to complete the inscription.

\$\endgroup\$
  • 1
    \$\begingroup\$ Impressive! I am new to the site, I apologize in advance if what follows are a couple of dumb questions. 1. Those are definitely 19 characters, but are they also 19 bytes? and 2. In what encoding that text would take 19 bytes? \$\endgroup\$ – damix911 Jul 19 at 6:43
  • \$\begingroup\$ Yeah, encoded in UTF-8 this will take 19 characters, but actually 51 bytes. With UTF-16, this still takes 39 bytes to encode. \$\endgroup\$ – ruohola Jul 19 at 8:53
  • 1
    \$\begingroup\$ @damix911 Charcoal has its own encoding, which can be found on its wiki. I think characters outside the code page cost 3 bytes. The deverbosifier tries to compute the correct length but it doesn't bother transcribing to the actual encoding, which is annoying. \$\endgroup\$ – Neil Jul 19 at 9:26
  • 1
    \$\begingroup\$ @Neil Okey, seems legit! \$\endgroup\$ – ruohola Jul 19 at 10:30
3
\$\begingroup\$

Japt -R, 19 16 bytes

z
ò@VÔtXUaVÊ)êÃê

Try it

z\nò@VÔtXUaVÊ)êÃê     :Implicit input of integer U & string V
z                     :Floor divide U by 2
 \n                   :Reassign result to U
   ò                  :Range [0,U]
    @                 :Map each X
     VÔ               :  Reverse V
       tX             :  Substring from index X to index ...
         Ua           :    Absolute difference between U and ...
           VÊ         :    Length of V
             )        :  End substring
              ê       :  Palindromise
               Ã      :End map
                ê     :Palindromise
                      :Implicit output, joined by newlines
\$\endgroup\$
2
\$\begingroup\$

Wolfram Language (Mathematica), 57 54 bytes

(g=Reverse@Rest@#~Join~#&)@BlockMap[g,#,⌈#2/2⌉,1]&

Try it online!

Takes the width as input.

\$\endgroup\$
  • 1
    \$\begingroup\$ @lirtosiast then the first g isn't evaluated the first time the function is called. Try it online! \$\endgroup\$ – attinat Jul 19 at 5:17
  • \$\begingroup\$ Interesting, any idea why it appears to work when you use @@ or @@@? \$\endgroup\$ – lirtosiast Jul 19 at 5:23
  • \$\begingroup\$ @lirtosiast It think Print/@f[...] -> Print/@Transpose[g[...]] -> Transpose[Print@g[...]], by which time g is defined. \$\endgroup\$ – attinat Jul 19 at 5:33
2
\$\begingroup\$

Japt -R, 10 bytes

Ôã°Vz)mê ê

Takes width instead of height.

Try it

Pseudocode (U is string, V is integer):

U.Reverse().AllSubstringsOfLength(++V / 2).Map(Palindromize).Palindromize
\$\endgroup\$
  • \$\begingroup\$ Nice! Never occurred to me to try to build it sideways. \$\endgroup\$ – Shaggy Jul 19 at 10:30
2
\$\begingroup\$

Perl 6, 68 67 bytes

{say |$^a.comb[{$_...0...$_}($a.comb-$^b+>1-1)X+.abs]for ^$b-$b+>1}

Try it online!

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

Python 3, 104 bytes

I haven't golfed in so long... I'm sure this could be shorter.

Details

This code defines a function that takes two arguments (the string and the height) and gives the result on standard output.

The index into the string is the Manhattan distance from the centre of the grid. For a grid of width w and height h, the distance for the cell at (x, y) is abs(x - (w - 1) / 2) + abs(v - (h - 1) / 2).

The width of the grid must be such that the Manhattan distance of the corners (say, (0, 0)) is one less than the length of the string. Substituting (0, 0) into the above and simplifying, we find that the width is simply 2 * len(s) - h.

Code

def b(s,h):
 w=2*len(s)-h
 for y in range(h):print(''.join(s[abs(x-w//2)+abs(y-h//2)]for x in range(w)))

Try it online!

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

05AB1E, 10 bytes

RŒI>;ù€ûû»

Try it online!

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

Pyth, 19 bytes

L+_btbjyyM.:Q-lQ/E2

Try it online!

L+_btbjyyM.:Q-lQ/E2   Implicit: Q=string, E=height
L                     Define a function, y(b):
  _b                    Reverse b
 +  tb                  Append all be first element of b
                      y is now a palindromisation function
              lQ      Length of Q
             -  /E2   Subtract floored division of E by 2
          .:Q         All substrings of Q with the above length
        yM            Palindromise each substring
       y              Palindromise the set
      j               Join on newlines, implicit print
\$\endgroup\$
1
\$\begingroup\$

Python 2, 95 bytes

def f(s,n):
 y=len(s);n//=2
 for i in range(n+1)+range(n)[::-1]:print s[y+~i:n-i:-1]+s[n-i:y-i]

Try it online!

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

Stax, 11 9 bytes

é─C[┬«#t▒

Run and debug it

It takes the width, and the original string, in that order.

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

C# (.NET Core), 146 bytes

s=>n=>{int w=s.Length*2-n,i=0,j;var r=new char[n,w];for(;i<n;i++)for(j=0;j<w;)r[i,j]=s[System.Math.Abs(n/2-i)+System.Math.Abs(w/2-j++)];return r;}

Try it online!

Longest answer so long. :-) It uses the Manhattan distance to the center of the square. There must be a shorter way, though.

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

Tcl, 188 170 162 bytes

{{w s} {join [lmap C [lrepeat $w string] {join [$C reverse [set y [$C range $s [set x [expr abs($w/2+1-[incr i])]] end-[expr $w/2-$x]]]][$C range $y 1 end]}] \n}} bytes

Try it online!

There seem to be a million bad ways to golf this problem in TCL. This is not the worst of them.

Saved 18 bytes minimum by converting to lambda (can save up to 13 more if return value of a list of lines is acceptable)

Saved an additional 8 since lmap iterator served as an extra constant

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

Canvas, 18 bytes

±X↕┌L╵┌-Y{x;1y1@]┼

Try it here!

Canvas doesn't do substrings, so I need to treat it like an art object and get a subsection that way. I feel like this costs me 2 bytes, but hey, what can you do.

Looks like this actually doesn't work like I thought: Canvas's palindromize functions mirror certain characters (e.g. V mirrored vertically becomes ^), and I can't exactly disable that... oh well, i guess

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

Ruby, 65 bytes

->s,h{(-(h/=2)..h).map{|y|(z=s[(w=y.abs)..w+~h]).reverse.chop+z}}

Try it online!

\$\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.