Eiffel Towers: Create a large "A" from "A"s

20

2

Create a function which given a number of lines n, makes a bigA.

  • The horizontal bar of bigA must be at the middle row, or the lower of the two if n is even
  • Assume a monospace font for output

Output should be a string (or similar, eg character array) with clear linebreaks to break up the lines, and with correct whitespace for left-padding (you can assume \t to be 4 spaces). There can be any whitespace on the right.

Examples

n = 1

A

n = 2

 A
AAA

n = 3

  A
 AAA
A   A

n = 4

   A
  A A
 AAAAA
A     A

n = 5

    A
   A A
  AAAAA
 A     A
A       A

This is inspired by Create an "H" from smaller "H"s

Budd

Posted 2018-03-23T01:00:41.080

Reputation: 349

May I add whitespace to the right side? Also, is trailing newline allowed? – Bubbler – 2018-03-23T01:12:54.853

@Bubbler, Any whitespace on the right side is fine, no trailing newline though – Budd – 2018-03-23T01:20:38.770

Are we allowed to return 2D character arrays instead of strings? (hint: it's usually recommended to allow any kind of output) – Olivier Grégoire – 2018-03-23T08:26:50.853

1@OlivierGrégoire Sure, as long as there is a clear break for the lines (eg an "\n" element, nested arrays) – Budd – 2018-03-23T09:00:24.633

Is an array of strings representing lines ok? Also, can I print directly to stdout? – Asone Tuhid – 2018-03-23T11:57:10.317

Yes, output is flexible as long as spacing and newlines are clearly represented somehow – Budd – 2018-03-23T12:33:23.750

Can we use another content character than "A" ? in particular, is lowercase "a" allowed ? – Ton Hospel – 2018-03-23T15:27:55.010

1@TonHospel, No, that really defeats the purporse of this – Budd – 2018-03-23T18:18:16.043

Can ____A\bA____ be used instead of ____A____ ? \b stands for ASCII backspace character. – Radek – 2018-03-23T22:12:35.150

Answers

12

05AB1E, 13 bytes

Code:

Ð;î¹)'A1376SΛ

Uses the 05AB1E encoding. Try it online!

Explanation:

Ð                  # Triplicate the input.
 ;î                # Compute ceiling(n / 2).
   ¹               # Push the first input again.
    )              # Wrap into an array. For input 7, this would result in:
                     [7, 7, 4, 7].
     'A            # Push the character 'A'
       1376S       # Push the array [1, 3, 7, 6]. These are the directions of the canvas.
                     This essentially translates to [↗, ↘, ↖, ←].
            Λ      # Write to canvas using the previous three parameters.

Canvas

I should probably document the canvas a little bit more (and a lot of other functions), but this basically sums it up. The canvas has different 'modes' based on the parameter types given. The canvas command has three parameters: <length> <string> <direction>.

Since the length and direction parameters are lists, it 'zips' these lists to create a set of instructions to be executed. The string parameter is just the letter A, so this is the fill character used by all instructions. The canvas interprets this as the following set of instructions (for input 7):

  • Draw a line of length 7 with the string A in direction
  • Draw a line of length 7 with the string A in direction
  • Draw a line of length 4 with the string A in direction
  • Draw a line of length 7 with the string A in direction

The directions are translated in the following manner:

7   0   1
  ↖ ↑ ↗
6 ← X → 2
  ↙ ↓ ↘
5   4   3

If nothing has been outputted, 05AB1E automatically outputs the canvas result.

Adnan

Posted 2018-03-23T01:00:41.080

Reputation: 41 965

1Thank you very much for the canvas explanation, that's a brilliant feature :-) – Kaldo – 2018-03-23T09:33:50.680

TIL triplicate is a word – Quintec – 2018-03-23T19:38:09.583

@thecoder16 quadruplicate, quintuplicate, ..., decuplicate – Magic Octopus Urn – 2018-03-26T13:56:47.130

Wow. I was doubtful of nonuplicate, but it exists as all the others do. Of course we have such useless words in English xD – Quintec – 2018-03-26T15:37:45.980

1376 can be Ž5' now. (Thanks for adding Ž, very useful!) Btw, the docs for the Canvas are still missing. ;) It's one of the few features for which I still have to look at the Elixir source code in order to fully see its capabilities. Especially since crosses are also possible with + or ×. PS: Would like to see a box single-char as well. And it would be useful if multiple characters could be mixed somehow, like - and |, or \ and /, or a box with + at the corners, etc. But that's perhaps something for later. – Kevin Cruijssen – 2018-11-07T08:50:44.673

If you don't have time, let me know. Then I will add it to the 05AB1E tip page for now. I see it can also be used cyclic, as you've done in this answer to create a spiral. Didn't knew Canvas could even be used like that!

– Kevin Cruijssen – 2018-11-07T09:09:19.090

1@KevinCruijssen Hey, apologies for all the late replies, it's been incredibly busy for me the last couple of weeks (I only managed to get 8 hours of sleep the last 72 hours haha) so I don't think I'm able to do anything right now, but feel free to add it to the tip page if you'd like. – Adnan – 2018-11-08T01:25:41.677

@Adnan Created the tip. If you see anything incorrect or something else worth mentioning, let me know. :)

– Kevin Cruijssen – 2018-11-08T13:42:50.743

6

Charcoal, 17 15 bytes

NθP×θAM⊘θ↗P^×θA

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

Nθ

Input n.

P×θA

Print the horizontal bar of the big A. (For even numbers, the n+1th overlaps the right side anyway.)

M⊘θ↗

Move to the top of the big A.

P^×θA

Print both sides of the big A.

Neil

Posted 2018-03-23T01:00:41.080

Reputation: 95 035

4

Python 2, 80 bytes

lambda n:'\n'.join(' '*(n+~i)+('A'+' A'[i==n/2]*n*2)[:i*2]+'A'for i in range(n))

Try it online!

Divide the desired output into the left whitespace, left A plus middle whitespace or As, and the right A. Compute the middle part using slicing on a fixed string. This allows to use the same way to generate the first line.

Bubbler

Posted 2018-03-23T01:00:41.080

Reputation: 16 616

4

Stax, 15 bytes

┴3╬*ôP^x'┌_╓J²♫

Run and debug it

Unpacked, ungolfed, and commented, the program looks like this.

m       map over [1 .. input] using rest of the program, output each result
'A      "A" literal
xhi=    is the iteration index equal to (integer) half the input?
65*     multiply by 65 (character code of "A")
]i*     repeat that character (" " or  "A") i times
+       concat to initial "A"
x)      left pad to the original input
|p      palindromize (concatenate the reverse minus the last character)

Run this one

recursive

Posted 2018-03-23T01:00:41.080

Reputation: 8 616

4

JavaScript (ES6), 77 bytes

This source code has a rectangle shape! Oh wait ... wrong challenge :-/

f=(n,k=n>>1,p='A')=>--n?f(n,k,' '+p)+`
${p}${(k-n?' ':'A').repeat(n*2-1)}A`:p

Try it online!

Arnauld

Posted 2018-03-23T01:00:41.080

Reputation: 111 334

4

Python 3.6, 79 bytes or 73 bytes

Using f-strings to align horizontal parts of the letter:

lambda n:'\n'.join(f"{'A'+' A'[i==n//2]*2*i:>{n+i}}"[:-1]+'A'for i in range(n))

With \b used to delete one A (possibly cheating):

lambda n:'\n'.join(f"{'A'+' A'[i==n//2]*2*i:>{n+i}}\bA"for i in range(n))

Radek

Posted 2018-03-23T01:00:41.080

Reputation: 171

3

Java (JDK 10), 124 bytes

n->{var a=new char[n][n+n-1];for(int c=n,r;c-->0;)for(r=n;r-->0;)a[r][n+n-c-2]=a[r][c]+=r==n/2&c>=r|r==n+~c?65:32;return a;}

Try it online!

Olivier Grégoire

Posted 2018-03-23T01:00:41.080

Reputation: 10 647

122 bytes – ceilingcat – 2019-12-19T22:33:33.583

3

J, 65 bytes

f=:3 :''' A''{~1(([:(<@;]+i.@+:)<.@-:)y)}([:(}:@|."1,.])=/~@i.)y'

Try it online!

It can be reduced by approx. 12 bytes by simply making the verb tacit, but I have problems doing it.

Explanation:

3 : '...' denotes an explicit one-liner verb

y is the argument

=/~@i. creates an identity matrix with size the argument

    =/~@i. 4
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

([:(}:@|."1,.]) prepends the identity matrix with its mirror copy with last elements of each row dropped.

    ]a =. ([:(}:@|."1,.])=/~@i.) 4
0 0 0 1 0 0 0
0 0 1 0 1 0 0
0 1 0 0 0 1 0
1 0 0 0 0 0 1

1(...)}(...) changes to 1 the positions in its right argument, selected by the left one

([:(<@;]+i.@+:)<.@-:) - prepares the selection by doing the following:

               <.@-: - halves the argument and finds the floor (finds the row number)
    <@;              - box the row, followed by a list of columns:  
        ]+i.@+:      - a list form the argumnt to the doubled row number

    ([:(<@;]+i.@+:)<.@-:) 4
┌───────────┐
│┌─┬───────┐│
││2│2 3 4 5││
│└─┴───────┘│
└───────────┘

    1(([:(<@;]+i.@+:)<.@-:) 4)}a
0 0 0 1 0 0 0
0 0 1 0 1 0 0
0 1 1 1 1 1 0
1 0 0 0 0 0 1

' A'{~ renders a space in the places of 0 and 'A' where there is 1

    ' A'{~1(([:(<@;]+i.@+:)<.@-:) 4)}a
   A   
  A A  
 AAAAA 
A     A

Galen Ivanov

Posted 2018-03-23T01:00:41.080

Reputation: 13 815

3

Canvas, 17 13 bytes

A×/╶½A×╶»╵:╋│

Try it here!

-4 bytes thanks to dzaima!

hakr14

Posted 2018-03-23T01:00:41.080

Reputation: 1 295

2

Japt -R, 20 19 bytes

Çç" A"gZ¶Uz¹i'A êÃû

Try it


Explanation

                        :Implicit input of integer U
Ç                       :Create the range [0,U) and pass each Z through a function
         Uz             :  Floor divide U by 2
       Z¶               :  Test for equality with Z (true=1, false=0)
  " A"g                 :  Get the character in the string " A" at that index
 ç                      :  Repeat Z times
           ¹            :  (Closes a few nested methods)
            i'A         :  Prepend an "A"
                ê       :  Palindromise
                 Ã      :End function
                  û     :Centre pad each element to the length of the longest element
                        :Implicitly join with newlines and output

Alternative

(In the hope that it might help me spot some savings!)

Æ'AúXÄ" A"gX¶Uz¹êÃû

Shaggy

Posted 2018-03-23T01:00:41.080

Reputation: 24 623

1Another alternate that's a byte longer: ç h'AUz)¬íp ®i'A êÃû – ETHproductions – 2018-03-23T15:19:59.010

@ETHproductions Replace pwith ² and it's also 19 bytes. – Shaggy – 2018-03-23T17:51:04.993

+1 way better than my monstrosity.

– Oliver – 2018-03-25T05:55:02.457

2

SOGL V0.12, 12 bytes

 A*:╚╥≤.»I:ž

Try it Here!

Explanation:

 A*           repeat "A" input times
   :          duplicate it
    ╚         create a "/" diagonal of one of the copies of As
     ╥        palindromize it horizontally
      ≤       get the other copy of the "A"s on top
       .»I:   push floor(input/2)+1 twice
           ž  and at those coordinates in the palindromized diagonals place in the row of As

dzaima

Posted 2018-03-23T01:00:41.080

Reputation: 19 048

2

Ruby, 66 bytes

->n{(0...n).map{|i|(s=(i==n/2??A:?\s)*2*i+?A)[0]=?A;?\s*(n+~i)+s}}

Try it online!

Returns as array of lines

Kirill L.

Posted 2018-03-23T01:00:41.080

Reputation: 6 693

1

Jelly, 23 20 19 18 bytes

=þ`o\L‘HĊƲ¦UŒBị⁾A 

Try it online!

=þ` creates an identity matrix of size n.

L‘HĊƲ finds the row index of the horizontal bar with ¦ picking that row out and applying o\ to it which creates the bar.

U reverses each row so we don't have an upside down "A" and ŒB (palindromize; vectorizes) makes the second half of the "A".

ị⁾A (with a space that is getting trimmed in the formatting) replaces 0s with spaces and 1s with As.

dylnan

Posted 2018-03-23T01:00:41.080

Reputation: 4 993

1

Ruby, 73 bytes

->n{(0...n).map{|i|(?A.ljust(i*2,i==n/2??A:' ')+(i>0??A:'')).center n*2}}

Try it online!

Asone Tuhid

Posted 2018-03-23T01:00:41.080

Reputation: 1 944

1

T-SQL, 182 177 bytes

DECLARE @n INT=5DECLARE @ INT=0a:DECLARE @s VARCHAR(9)=STR(POWER(10,@),@n)PRINT REPLACE(REPLACE(@s+REVERSE(LEFT(@s,@n-1)),'1','A'),'0',IIF(@=@n/2,'A',' '))SET @+=1IF @<@n GOTO a

First version (with 182 bytes):

DECLARE @n INT=5DECLARE @ INT=0WHILE @<@n BEGIN DECLARE @s VARCHAR(9)=STR(POWER(10,@),@n)PRINT REPLACE(REPLACE(@s+REVERSE(LEFT(@s,@n-1)),'1','A'),'0',IIF(@=@n/2,'A',' '))SET @+=1 END

The version above works up to @n=9.

Here is another version, which works up to @n=23, but has 2 extra bytes:

DECLARE @n INT=5DECLARE @ INT=0WHILE @<@n BEGIN DECLARE @s VARCHAR(23)=STR(POWER(10.,@),@n)PRINT REPLACE(REPLACE(@s+REVERSE(LEFT(@s,@n-1)),'1','A'),'0',IIF(@=@n/2,'A',' '))SET @+=1 END

Ungolfed:

DECLARE @n INT=5

DECLARE @i INT=0
WHILE @i<@n BEGIN
    DECLARE @s VARCHAR(9)=STR(POWER(10,@i),@n)
    PRINT REPLACE(REPLACE(@s+REVERSE(LEFT(@s,@n-1)),'1','A'),'0',IIF(@i=@n/2,'A',' '))
    SET @i+=1
END

Razvan Socol

Posted 2018-03-23T01:00:41.080

Reputation: 341

1

Haskell, 98 97 95 bytes and 109 bytes

Two very different approaches. First (95 bytes):

c!n=([1..n]>>c)++"A"
f n=unlines[" "!(n-x)++drop 3([" "!(abs$n`div`2-x+1)!!0]!(2*x))|x<-[1..n]]

and second (109 bytes):

m True='A'
m _=' '
g n=unlines[[m(abs(n-j)==l||l==q&&elem j[q+1..q+n])|j<-[1..2*n]]|l<-[0..n-1],q<-[n`div`2]]

Try them here!; Try modified version here!

Try third version here!

Radek

Posted 2018-03-23T01:00:41.080

Reputation: 171

Welcome to PPCG! You can save a byte on your first approach by defining l as infix operator.

– Laikoni – 2018-03-25T01:44:03.203

m True='A' an be shortened to m b|b='A'. – Laikoni – 2018-03-25T01:47:31.810

It turned out that even two bytes could be saved. Thanks! :) – Radek – 2018-03-25T13:16:10.157

1

Python 2, 70 bytes or 65 bytes

List of strings is acceptable result, as @Budd stated in comments.

lambda n:['%*sA\n'%(n+i,('A'+i*2*' A'[i==n/2])[:-1])for i in range(n)]

Try it online!


Seemingly cheaty solution, using \b. It looks funky in TIO, in console it does the job.

lambda n:['%*s\bA\n'%(n+i,'A'+i*2*' A'[i==n/2])for i in range(n)]

Try it online!

Dead Possum

Posted 2018-03-23T01:00:41.080

Reputation: 3 256

0

Javascript, 124 bytes

A fairly naive solution, gave it a shot to practice js skills.

for(i=-1,p=" ".repeat(n-1)+"A ";++i<n;console.log(i-~~(n/2)?p:p.slice(0,i)+"A".repeat(n)),p=p.slice(1,n)+" "+p.slice(n-1)){}

Unpacked

for(
 //create the first line
 i=-1, p=" ".repeat(n-1)+"A "; 
 ++i<n;
 console.log( 
 //if we are not at the bar
      i-~~(n/2)?
 //otherwise, use the modified previous line
      p
 //slice the start of the previous line and add As
      :p.slice(0,i)+"A".repeat(n)), 
 //add a space in between the previous line and remove padding on each side
 p=p.slice(1,n)+" "+p.slice(n-1)){}

Budd

Posted 2018-03-23T01:00:41.080

Reputation: 349

0

Python 3, 93, 88 bytes

lambda n:'\n'.join(f"{'A'+(x>0)*('A '[x!=n//2]*(x*2-1)+'A'):^{n*2-1}}"for x in range(n))

Try it online!

-3 by @ovs using f-string

Rick Rongen

Posted 2018-03-23T01:00:41.080

Reputation: 223

0

Perl 5 -n, 57 bytes

#!/usr/bin/perl -n
say$"x-$_.uc(A x($n+$_&-2?1:$n*2)|$"x2x$n++.A)for 1-$_..0

Try it online!

Ton Hospel

Posted 2018-03-23T01:00:41.080

Reputation: 14 114