16
\$\begingroup\$

In this challenge you are going to place letters from the alphabet in a Cartesian plane and output the result as a text.

Your input will consist in a list of list with 3 parameters:

  • X coordinate
  • Y coordinate
  • String

How?

We know that a Cartesian plane contain 2 axes \$(X, Y)\$ and 4 quadrants where the signs of the \$(X,Y)\$ coordinates are \$(+,+)\$, \$(−,+)\$, \$(−,−)\$, and \$(+,−)\$. For example

Consider the following 3 by 3 matrix as a Cartesian plane

\begin{matrix} (-1,1) & (0,1) & (1,1) \\ (-1,0) & (0,0) & (1,0) \\ (-1,-1) & (0,-1) & (1,-1) \end{matrix}

If we are given in the input something like [[-1,1,L],[0,1,F]] our matrix will look something similar to

\begin{matrix} L & F & (1,1) \\ (-1,0) & (0,0) & (1,0) \\ (-1,-1) & (0,-1) & (1,-1) \end{matrix}

And the final output LF

In addition to that there are some points we need to follow in order to get the correct output:

  • When a X,Y coord is repeated, you will need to concatenate the strings. Example: assume in (-1,1) the string F is placed and you need to place the string a in the same point. You concatenate both strings resulting in Fa and that is the value that will go in (-1,1).
  • Your output need to be consistent to the matrix. Example imagine this as your final result:

\begin{matrix} Ma & r & ie \\ i & s & (1,0) \\ cute & (0,-1) & (1,-1) \end{matrix}

You must output

Ma  rie 
i   s       
cute

Why?

You can view this as a table where the columns are the values of the x-axis and the rows the y-axis.

        Column 1    |   Column 2    |   Column 3
        ----------------------------------------
Row 1   |  "Ma"     |      "r"      |     "ie" 
Row 2   |  "i"      |      "s"      |
Row 3   |  "cute"   |               |

All columns values must have the same length

        Column 1    |   Column 2    |   Column 3
        ----------------------------------------
Row 1   |  "Ma  "   |      "r"      |     "ie" 
Row 2   |  "i   "   |      "s"      |
Row 3   |  "cute"   |               |

Finnaly we output the result

Ma  rie
i   s
cute

Test Cases

Input
------------
[[3, 3, "c"]
[4, 1, "un"]
[5, 3, "e"]
[4, 3, "od"]
[4, 2, "lf"]
[1, 2, "go"]
[2, 1, "i"]
[2, 1, "s f"]]

Output
--------------
      code
go     lf 
  is f un

Input
--------------
[[0, 0, 's'],
[-1,1, 'M'],
[0, 1, 'r'],
[-1,1, 'a'],
[1, 1, 'i'],
[-1, 0, 'i'],
[1, 1, 'e'],
[-1,- 1, 'c'],
[-1,- 1, 'u'],
[-1, -1, 'te']]

Output.
----------------
Ma  rie
i   s
cute

Notes

  • This is supposed to be
  • You can wrap the coordinates in a single list e.g [[3, 3], "c"]
  • You can take the input in any reasonable format
  • You can assume there wont be any number or empty spaces only in the input. e.g. There can be something like a a but never 1 or " " or 1a or 1 1
\$\endgroup\$
10
  • \$\begingroup\$ sandbox \$\endgroup\$ Feb 5, 2019 at 14:53
  • 1
    \$\begingroup\$ @KevinCruijssen You can assume there wont be any number or empty spaces only in the input. There can be something like a a but never 1 or ` ` or 1a or 1 1 \$\endgroup\$ Feb 5, 2019 at 17:52
  • 1
    \$\begingroup\$ @LuisfelipeDejesusMunoz Thanks. Oh, and one more question I'm sure more people here would want to know: who is Marie? ;p \$\endgroup\$ Feb 5, 2019 at 18:02
  • 2
    \$\begingroup\$ @KevinCruijssen My crush 5 years ago :c \$\endgroup\$ Feb 5, 2019 at 18:02
  • 1
    \$\begingroup\$ Can we take input as a list of named tuples? Something like this: (int a,int b,string c)? \$\endgroup\$
    – Gymhgy
    Feb 5, 2019 at 19:23

7 Answers 7

9
\$\begingroup\$

JavaScript (ES8),  186 180  179 bytes

Saved 1 byte thanks to @Shaggy

a=>(g=d=>a.some(([x,y,s])=>(w[x+=d]>(l=((r=o[y=d-y]=o[y]||[])[x]=[r[x]]+s).length)||(w[x]=l),x|y)<0,w=[o=[]])?g(-~d):o.map(r=>w.map((w,x)=>(r[x]||'').padEnd(w)).join``).join`
`)``

Try it online!

Negative indices in JS (or the lack of them)

Given an array A[], it's perfectly legal in JS to do something like A[-1] = 5. However, this will not save the value in the array itself. Instead, it will implicitly coerce this negative index to a string ("-1") and set the corresponding property in the surrounding object of the array.

The bad news is that properties are not iterable with methods such as map():

a = [];
a[1] = 3;
a[-1] = 5;
a.map((v, i) => console.log(v + ' is stored at index ' + i))

Try it online!

The above code will only display 3 is stored at index 1.

A possible workaround would be:

a = [];
a[1] = 3;
a[-1] = 5;
Object.keys(a).map(k => console.log(a[k] + ' is stored with key ' + k))

Try it online!

But:

  • This is not very golf-friendly.
  • The keys are not sorted in numerical order.

What we do here

We definitely want to work with positive values of both \$x\$ and \$y\$ in order to avoid the problems described above.

We could do a first pass on the data, looking for the minimum value of \$x\$ and the minimum value of \$y\$. But that would be quite lengthy.

Here's what we do instead:

  • we start with \$d=0\$
  • we process an iteration where \$x\$ is replaced with \$x+d\$ and \$y\$ is replaced with \$d-y\$
  • if we have either \$x<0\$ or \$y<0\$ for any entry, we abort and recursively start another attempt with \$d+1\$
\$\endgroup\$
2
  • \$\begingroup\$ I think you can save a byte by declaring o within w: w=[o=[]]. \$\endgroup\$
    – Shaggy
    Feb 5, 2019 at 17:56
  • \$\begingroup\$ @Shaggy I think that's safe indeed. Thanks. :) \$\endgroup\$
    – Arnauld
    Feb 5, 2019 at 18:23
6
\$\begingroup\$

APL (Dyalog Unicode), 39 bytesSBCS

Anonymous infix lambda taking* lists of coordinates and strings as left and right arguments.

{⊃,/↑¨↓⌽m⊣m[c],←⍵⊣m←(⊃⌈/c←1+⍺-⌊/⍺)⍴⊂''}

Try it online!

{} "dfn"; left (coordinates) and right (strings) arguments are and :

⊂'' enclosed empty string, so use as fill for an array

()⍴ cyclically reshape into an array of the following dimensions:

  ⌊/⍺ the lowest value along each axis of the coordinates

  ⍺- subtract that from all the coordinates

  1+ add that to one (since we want the inclusive range)

  c← store in c (for coordinates)

  ⌈/ the highest value along each axis of those

   unpack to use as dimensions

m← store in m (for matrix)

⍵⊣ discard that in favour of the strings

m[c],← append those to m at the coordinates c

m⊣ discard those in favour of the amended m

 mirror

 split into list of lists of strings

↑¨ mix each list of strings into a character matrix, padding with spaces

,/ reduce by horizontal concatenation

 unpack (since reduction reduces rank from 1 to 0)


* If taking a single argument of interwoven coordinates and strings is required, it will be 5 bytes longer.

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

Python 2, 188 185 181 bytes

s=sorted;d={};k={}
for x,y,c in input():d[x]=d.get(x,{});k[~y]=d[x][y]=d[x].get(y,'')+c
for y in s(k):print''.join('%*s'%(-max(map(len,d[x].values())),d[x].get(~y,''))for x in s(d))

Try it online!

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 45 44 bytes

WsàŸãεUõIvyнXQiyθ«]IZsß->ôεíDéθgjí}øRJʒðKĀ}»

Takes the input-coordinates as an inner list.

Try it online or verify all test cases.

Explanation:

Wsà           # Get the minimum and maximum of the (implicit) input-list
   Ÿ          # Create a list in the range [min, max]
    ã         # Create each possible pair by taking the cartesian product with itself
ε             # Map each coordinate to:
 U            #  Pop and store the coordinate in variable `X`
 õ            #  Push an empty string ""
  Iv          #  Loop `y` over the input-items:
    yн        #   Get the coordinates of item `y`
      XQi     #   If it's equal to variable `X`:
         yθ   #    Get the string of item `y`
           «  #    Concat it to the (non-)empty string
]             # Close the if-statement, loop, and map
 IZsß         # Get the maximum and minimum of the input-list
     -        # Subtract them from each other
      >       # And increase it by 1
       ô      # Split the list into parts of this size
ε             # Map each part to:
 í            #  Reverse each inner string
  Déθg        #  Get the length of the longest inner string
      j       #  Prepend spaces to each item up to that length
       í      #  And reverse every item back again
              #  (so the spaces are trailing instead of leading)
}ø            # After the map: zip/transpose; swapping rows/columns
  R           # Reverse the entire list
   J          # Join each inner list together to a single string
ʒðKĀ}         # Remove all strings consisting only of spaces
     »        # Join the strings by newlines (and output implicitly)
\$\endgroup\$
3
\$\begingroup\$

Charcoal, 60 bytes

≔Eθ§ι¹η≔Eθ§ι⁰ζF…·⌊ζ⌈ζ«≔E…·⌊η⌈η⭆θ⎇∧⁼ι§μ⁰⁼κ§μ¹§μ²ωε⮌εM⌈EεLκ±Lε

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

≔Eθ§ι¹η≔Eθ§ι⁰ζ

Extract the coordinates from the input.

F…·⌊ζ⌈ζ«

Loop over the x-coordinates.

≔E…·⌊η⌈η⭆θ⎇∧⁼ι§μ⁰⁼κ§μ¹§μ²ωε

Loop over the y-coordinates, extracting and concatenating all of the strings at the given coordinates.

⮌ε

Print the strings in reverse order as the y-coordinates are reversed compared to Charcoal's coordinate system.

M⌈EεLκ±Lε

Move to the start of the next column.

\$\endgroup\$
3
\$\begingroup\$

Perl 5 -p00 -MList::Util=max, 148 bytes

s/(\S+) (\S+) (.*)
/$a{$1}=max$a{$1},length($h{$2}{$1}.=$3);''/ge;for$y(sort{$b-$a}keys%h){map{printf"%-$a{$_}s",$h{$y}{$_}}sort{$a-$b}keys%a;say""}

TIO

How

  • s/(\S+) (\S+) (.*) / ... ;''/ge;, substitution flags /g loop /e eval, replacement evaluates to empty clearing line input/default variable
  • $a{$1}=max$a{$1},length($h{$2}{$1}.=$3), autovivifies a map %h of map whose first level keys y second level x and concatenate string $3 to the value, get the length and autovivifies a second map %a whose keys x and value the max of length over the column (x)
  • for$y(sort{$b-$a}keys%h){ ... ;say""}, for row indices $y in keys of %h sorted numerically reverse, say"" at the end to print a newline
  • map{ ... }sort{$a-$b}keys%a, for column index $_ in keys %a sorted numerically
  • printf"%-$a{$_}s",$h{$y}{$_}, print string aligned to the left with column width
\$\endgroup\$
3
\$\begingroup\$

Clean, 212 206 bytes

import StdEnv,StdLib
? =minList
m=maxList
c=flatten
$a#(x,y,z)=unzip3 a
=flatlines(map c(transpose[[ljustify(m(map length l))k\\l<-[reverse[c[s\\(u,v,s)<-a|u==i&&v==j]\\j<-[?y..m y]]],k<-l]\\i<-[?x..m x]]))

Try it online!

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