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 7 years ago

Reputation: 349

May I add whitespace to the right side? Also, is trailing newline allowed? – Bubbler – 7 years ago

@Bubbler, Any whitespace on the right side is fine, no trailing newline though – Budd – 7 years ago

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 – 7 years ago

1@OlivierGrégoire Sure, as long as there is a clear break for the lines (eg an "\n" element, nested arrays) – Budd – 7 years ago

Is an array of strings representing lines ok? Also, can I print directly to stdout? – Asone Tuhid – 7 years ago

Yes, output is flexible as long as spacing and newlines are clearly represented somehow – Budd – 7 years ago

Can we use another content character than "A" ? in particular, is lowercase "a" allowed ? – Ton Hospel – 7 years ago

1@TonHospel, No, that really defeats the purporse of this – Budd – 7 years ago

Can ____A\bA____ be used instead of ____A____ ? \b stands for ASCII backspace character. – Radek – 7 years ago

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 7 years ago

Reputation: 41 965

1Thank you very much for the canvas explanation, that's a brilliant feature :-) – Kaldo – 7 years ago

TIL triplicate is a word – Quintec – 7 years ago

@thecoder16 quadruplicate, quintuplicate, ..., decuplicate – Magic Octopus Urn – 7 years ago

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 – 7 years ago

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 – 6 years ago

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 – 6 years ago

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 – 6 years ago

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

– Kevin Cruijssen – 6 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

Reputation: 10 647

122 bytes – ceilingcat – 5 years ago

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 7 years ago

Reputation: 13 815

3

Canvas, 17 13 bytes

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

Try it here!

-4 bytes thanks to dzaima!

hakr14

Posted 7 years ago

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 7 years ago

Reputation: 24 623

1Another alternate that's a byte longer: ç h'AUz)¬íp ®i'A êÃû – ETHproductions – 7 years ago

@ETHproductions Replace pwith ² and it's also 19 bytes. – Shaggy – 7 years ago

+1 way better than my monstrosity.

– Oliver – 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

Reputation: 171

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

– Laikoni – 7 years ago

m True='A' an be shortened to m b|b='A'. – Laikoni – 7 years ago

It turned out that even two bytes could be saved. Thanks! :) – Radek – 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

Reputation: 14 114