4
\$\begingroup\$

I don't know if something like this exists already (and I'm not finding the right key words) but if not, it felt like it could be an interesting coding puzzle.

The challenge is, to take an arbitrarily nested list (no more than 2 deep), and display the content in a terminal in 2 dimensions in a 'pretty' manner. Each 'top level' dictionary element should read left - right, and the nested content for each top level index should be displayed vertically in line with its index position.

Example input:

[["A"], ["B", "C"], ["D"], ["E", "F", "G"], ["H"]]

Expected output (option 1):

 A B D E H
   C   F
       G

Expected output (option 2):

In this case, 'stacks' should be as close to centralised as possible, so there is a similar amount of content above and below the top level left-to-right content.

       E
 A B D F H
   C   G

Example input 2

List contents (for the purpose of this challenge) can be any length, but will always be the same length. e.g.

[["ABC"], ["BCD", "CDE"], ["DEF"], ["EFG", "FGH", "GHI"], ["HIJ"]]

Would also be valid, and should be rendered in similar fashion to example 1:

                                             EFG
ABC BCD DEF EFG HIJ      or      ABC BCD DEF FGH HIJ
    CDE     FGH                      CDE     GHI
            GHI

Other input considerations (updated in response to comments):

  • The indexes of the top level, and nested lists will never be empty.

Criteria:

  • The solution should take a list of lists (nested 1 deep).

  • The format of the output is flexible, but it should be clear which elements of the list are distinct at the top level (left to right, in my example separated by spaces) and which elements of the sublists are which (top to bottom, separated vertically on successive lines in my example).

  • Each item in a sublist inside the list should be printed aligned with each other in the vertical direction.

  • I don't care about speed/complexity/byte count, so at the highest level the criteria will be considered met by any code that can produces the desired 2D output. The winner is therefore a popularity-contest, in that most votes wins (edit: now that answers have started being added the winner will be the answer with the most votes 1 week from today, but new answers would always be welcome).

Bonus points:

  • How 'pretty' the output is, I'll leave to you. Whether you want it to 'cascade' from the top most character as example 1, or a pseudo-centrally aligned output as example 2. Any other creative solutions are also welcomed.

  • Code which can handle variable length strings in any position.


I'm particularly interested in Python solutions, but anything goes.

\$\endgroup\$

closed as unclear what you're asking by xnor, Chas Brown, Jo King, Shaggy, Xcali Jan 11 at 21:44

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    \$\begingroup\$ Welcome to PPCG! There are a couple of issues with this post: 1) All challenges here must have an objective winning criterion. How pretty the output is, on the other hand, is rather subjective. 2) "in a 'pretty' manner" is unclear. Just how flexible is the output? What rules must the pretty-print version abide to? 3) I recommend using the Sandbox in the futute to get feedback prior to posting to the main site. \$\endgroup\$ – Mr. Xcoder Jan 9 at 9:58
  • 3
    \$\begingroup\$ Why would the "C" align under the "A" (and "F" under "D") in the option 1 example? (Shouldn't there be leading spaces, like this?) \$\endgroup\$ – Jonathan Allan Jan 9 at 10:15
  • 2
    \$\begingroup\$ This should not be reopened yet. Popularity contests do have the winner decided on votes, but they still need an objective winning criterion (for pop cons, it should be what you should vote based on). What makes an answer 'good'? 'Pretty' output? Aesthetically pleasing code? or what? You need to provide a guideline of how what makes answers vote-worthy, or this lacks an objective win criterion. \$\endgroup\$ – Riker Jan 10 at 1:28
  • 4
    \$\begingroup\$ If we accept for now the popularity contest winning criterion, I still think there's the issue that answers are being judged on the aesthetic value of the output representation and not the code or algorithm that produces it, putting it outside of site scope. It seems to me that once one has decided on a nice presentation of the output, it shouldn't be hard for experienced coders to write code that implements it. I think this could be made more programming-focused with complex multilayered inputs that are hard to present in a clean human-readable way. \$\endgroup\$ – xnor Jan 11 at 7:54
  • 3
    \$\begingroup\$ I should also warn you that at this point in the site, popularity-contest might just be a historical relic that tends to lure newbs into posting challenges that get downvoted or closed. And, there might not be anything you can do to make a pop-con palatable to a good fraction of the site audience. Also, past pop-cons suggest that if the challenge does take off, there's a good chance you'll get mostly (or exclusively) solutions that are not in the spirit of what you ask for, even if you've clearly explained what that is. \$\endgroup\$ – xnor Jan 11 at 8:02
2
\$\begingroup\$

Golfed - Jelly, 4 bytes

z“”G

Try it online!

Pretty Printing with boxes - Python 3, 656 bytes

def f(matrix):
	length = max(map(len, matrix))
	lengths = []
	for index in range(len(matrix)):
		matrix[index] = ([""] * -((len(matrix[index]) - length) // 2) + matrix[index] + ([""] * ((length - len(matrix[index])) // 2)))
		hlength = max(map(len, matrix[index]))
		lengths.append(hlength)
		matrix[index] = [item.ljust(hlength) for item in matrix[index]]
	horiz = ["─" * e for e in lengths]
	print("┬".join(horiz).join("┌┐"))
	for row in list(zip(*matrix))[:-1]:
		print("│".join(row).join("││"))
		print("┼".join(horiz).join("├┤"))
	print("│".join(col[-1] for col in matrix).join("││"))
	print("┴".join(horiz).join("└┘"))

Try it online!

Pretty Printing original (even spacing) - Python 3, 371 bytes

def f(matrix):
	length = max(map(len, matrix))
	for index in range(len(matrix)):
		matrix[index] = ([""] * -((len(matrix[index]) - length) // 2) + matrix[index] + ([""] * ((length - len(matrix[index])) // 2)))
		hlength = max(map(len, matrix[index]))
		matrix[index] = [item.ljust(hlength) for item in matrix[index]]
	for row in list(zip(*matrix)):
		print(" ".join(row))

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ Very cool solutions! Particularly like the boxes. \$\endgroup\$ – Joe Healey Jan 11 at 14:07
2
\$\begingroup\$

05AB1E

Since this is a , I wasn't entirely sure how to answer (might have been best to not answer at all, but I figured I'd gave it a shot anyway). I've added two answers below: one submission I would normally post and one 'pretty output' submission with multiple options (which isn't golfed whatsoever, might do so as well later on). If the rules have been clarified I will update (or delete) accordingly.

Code-golf submission (7 bytes):

ннgð×ζ»

(Based on the current test cases, so assumes all string items are of the same length.)
Outputs in a similar matter as the first examples in the test cases of the challenge description.

Try it online or verify all test cases.

Explanation:

н        # Take the first inner list of the (implicit) input
         #  i.e. [["ABC"],["BCD","CDE"],["DEF"],["EFG","FGH","GHI"],["HIJ"]] → ["ABC"]
 н       # Pop and take the first string of that
         #  i.e. ["ABC"] → "ABC"
  g      # Pop and get it's length
         #  i.e. "ABC" → 3
   ð×    # Push a space character " " and increase it to that size
         #  i.e. 3 → "   "
     ζ   # Zip/transpose (swapping rows/columns) of the (implicit) input,
         # with the spaces-string as filler
         #  i.e. [["ABC"],["BCD","CDE"],["DEF"],["EFG","FGH","GHI"],["HIJ"]] and "   "
         #   → [["ABC","BCD","DEF","EFG","HIJ"],["   ","CDE","   ","FGH","   "],["   ","   ","   ","GHI","   "]]
      »  # Join by newlines (which implicitly joins inner lists by spaces)
         #  → "ABC BCD DEF EFG HIJ\n    CDE     FGH    \n            GHI    "
         # (and output the result implicitly)

'Pretty output' submission with options:

Here we take an additional integer input as input, and 'pretty print' the output based on the option:

1: ABC BCD DEF EFG HIJ
       CDE     FGH    
               GHI    

2:             GHI    
       CDE     FGH    
   ABC BCD DEF EFG HIJ

3:             EFG    
   ABC CDE DEF FGH HIJ  
       BCD     GHI    

4:     CDE     EFG    
   ABC     DEF FGH HIJ
       BCD     GHI    

As for the code (it's not golfed or properly tested whatsoever, as can be seen quite easily XD):

i
 ннgð×ζ»
ë¹<i
 ннgð×ζR»
ë¹Íi
 ннgð×ζøε2ä}DεθR}ø»,€нø»,
ë¹4Qi
 ннgðשζøεD®¢._}ø»
ë
 ¹"Option ÿ is not available."

Try it online or see all options in action.

\$\endgroup\$
  • \$\begingroup\$ Nice with the alternative output options! \$\endgroup\$ – Joe Healey Jan 11 at 14:01
2
\$\begingroup\$

JavaScript (Node.js), 112 107 105 bytes

-1 byte thanks to @Kevin

Despite the controversy in the comments, I gave it a shot. It's my first ever codegolf submission and I had a lot of fun making it.

Tips & tricks are more than welcome!

a=>{o=['','',''];for(b of a)for(c=3;c--;)o[c]+=(b[c]?b[c]:' '.repeat(b[0].length))+' ';return o.join`\n`}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I'm not skilled in JS codegolfing, so I'm sure a lot more can be golfed, but one thing I noticed is that you can remove the brackets around the outer loop and add a semi-colon before the return instead to save 1 byte. \$\endgroup\$ – Kevin Cruijssen Jan 11 at 13:31
  • \$\begingroup\$ @KevinCruijssen thanks for the tip! I've change my code \$\endgroup\$ – T. Dirks Jan 11 at 13:40
  • 1
    \$\begingroup\$ Yw, and welcome to PPCG! :) If you haven't seen it yet, Tips for golfing in JavaScript and Tips for golfing in <all languages> might be interesting to read through. Enjoy your stay! \$\endgroup\$ – Kevin Cruijssen Jan 11 at 13:52
1
\$\begingroup\$

PHP, 162 160 bytes

Even though this isn't code-golf, here's the golfed version anyway:

function($t){$r=0;while($b=array_column($t,$r,0)){if($r++==$y=0)$a=$b;foreach($a as$k=>$x)printf("% -".max(array_map('strlen',$t[$y++]))."s ",$b[$k]);echo"
";}}

Try it online!

And ungolfed:

function nested( $t ) {
	$r = 0;
	while ( $b = array_column( $t, $r, 0 ) ) {
		if ( $r++ === 0 ) $a = $b;
		$y = 0;
		foreach( $a as $k => $x ) {
			$l = max( array_map('strlen', $t[$y++] ) );
			printf( "% -". $l ."s ", $b[$k] );
		}
		echo "\n";
	}
}

Tests:

[["A"], ["B", "C"], ["D"], ["E", "F", "G"], ["H"]],
[["A"], ["B2", "C"], ["D"], ["E", "FGH", "G"], ["H"]],
[["ABC"], ["BCD", "CDE"], ["DEF"], ["EFG", "FGH", "GHI"], ["HIJ"]],
[["ABC"], ["BCD", "CDEF"], ["DEF"], ["EFG", "FGH", "GHIII"], ["HIJK"]],
[["ABC123","FOO","BCD", "CDEF","BAR"], ["BCD", "PPCG_RULEZ"], ["DEF"], ["EFG", "FGH", "GHIII","BCD", "CDE"], ["HIJK"]]

This will line up columns for strings of any length. Also, any number of rows will display fine too.

Output:

A B D E H 
  C   F   
      G   

A B2 D E   H 
  C    FGH   
       G     

ABC BCD DEF EFG HIJ 
    CDE     FGH     
            GHI     

ABC BCD  DEF EFG   HIJK 
    CDEF     FGH        
             GHIII      

ABC123 BCD        DEF EFG   HIJK 
FOO    PPCG_RULEZ     FGH        
BCD                   GHIII      
CDEF                  BCD        
BAR                   CDE   
\$\endgroup\$
0
\$\begingroup\$

Python 3, 153 chars

Tried desperately to get this to work with a list comprehension, but here is my attempt.

l=len;p=print
for j in range(l(max(x,key=l))):
  for i in range(l(x)):
    if(l(x[i])>j):p(x[i][j],end=' ')
    else:p(' '*l(x[i][0]),end=' ')
  p()
\$\endgroup\$
0
\$\begingroup\$

C# (.NET Core), 205 bytes

Without LINQ.

Takes in a jagged array and prints the junk out.

p=>{var i=p.Length;int q,j=0;for(q=0;q<i;q++){var z=p[q].Length;j=z>j?z:j;}var s="";for(q=0;q<j;q++){for(var k=0;k<i;){try{s+=p[k++][q]+" ";}catch{s+=new string(' ',p[0][0].Length+1);}}s+="\n";}return s;};

Try it online!

\$\endgroup\$

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