Fit a word into an alphabet grid

shooqie 09/05/2017. 23 answers, 1.214 views
code-golf string ascii-art alphabet

Inspired by a meme I saw earlier today.

Challenge description

Consider an infinite alphabet grid:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
...

Take a word (CODEGOLF in this example) and make it a subsequence of the grid, replacing unused letters by a space and removing letters at the end of the infinite grid altogether:

  C           O           
   DE G       O           
           L              
     F

Examples

STACKEXCHANGE

                  ST      
A C       K               
    E                  X  
  C    H                  
A            N            
      G                   
    E

ZYXWVUTSRQPONMLKJIHGFEDCBA

                         Z
                        Y 
                       X  
                      W   
                     V    
                    U     
                   T      
                  S       
                 R        
                Q         
               P          
              O           
             N            
            M             
           L              
          K               
         J                
        I                 
       H                  
      G                   
     F                    
    E                     
   D                      
  C                       
 B                        
A

F

     F

ANTIDISESTABLISHMENTARIANISM

A            N     T      
        I                 
   D    I         S       
    E             ST      
AB         L              
        I         S       
       H    M             
    E        N     T      
A                R        
        I                 
A            N            
        I         S       
            M

Notes

  • Trailing whitespaces are allowed.
  • You don't need to pad the last any line with spaces. For example, if the input is ABC, you may output just ABC without 23 trailing spaces.
  • You may assume input will match [A-Z]+ regex.
  • Alternatively, you may use lower-case alphabet, in which case output will match [a-z]+.
  • You must use a newline (\n, \r\n or equivalent) to separate lines, that is a list of strings is not a proper output format.
  • This is a challenge, so make your code as short as possible!
5 Comments
Erik the Outgolfer 09/02/2017
Are leading newlines allowed?
shooqie 09/02/2017
@EriktheOutgolfer Sure, as long as it doesn't mess up grid structure.
Zacharý 09/02/2017
Would it be okay if a non-fatal error stops the program?
shooqie 09/02/2017
@Zacharý Although I can see how that could save some bytes, I think it's ugly and produces undesired, superfluous output. So no. EDIT: Unless you can make your program non-fatally exit through an exit code or something that wouldn't print exception stack trace or something similar to stderr.
Zacharý 09/02/2017
Okay, my answer doesn't error.

23 Answers


Zgarb 09/02/2017.

Husk, 15 bytes

TṪS`?' €…"AZ"ġ>

Try it online!

Explanation

TṪS`?' €…"AZ"ġ>  Implicit input, e.g. "HELLO"
             ġ>  Split into strictly increasing substrings: x = ["H","EL","LO"]
        …"AZ"    The uppercase alphabet (technically, the string "AZ" rangified).
 Ṫ               Outer product of the alphabet and x
  S`?' €         using this function:
                   Arguments: character, say c = 'L', and string, say s = "EL".
       €           1-based index of c in s, or 0 if not found: 2
  S`?'             If this is truthy, then c, else a space: 'L'
                 This gives, for each letter c of the alphabet,
                 a string of the same length as x,
                 containing c for those substrings that contain c,
                 and a space for others.
T                Transpose, implicitly print separated by newlines.

edc65 09/02/2017.

JavaScript (ES6), 79

Edit As a leading newline is accepted, I can save 2 bytes

s=>eval("for(o='',v=i=0;c=s.charCodeAt(i);v%=27)o+=v++?c-63-v?' ':s[i++]:`\n`")

For 1 byte more, I can accept lowercase or uppercase input:

s=>eval("for(o='',v=i=0;c=s[i];v%=27)o+=v++?parseInt(c,36)-8-v?' ':s[i++]:`\n`")

Less golfed

s=>{
  var i,o,c,v
  for(o = '', v = 1, i = 0; c = s.charCodeAt(i); v %= 27)
    o += v++ ? c-63-v ? ' ' : s[i++] : '\n'
  return o
}  

Test

f=s=>eval("for(o='',v=i=0;c=s.charCodeAt(i);v%=27)o+=v++?c-63-v?' ':s[i++]:`\n`")

function update() {
  var i=I.value
  i=i.replace(/[^A-Z]/gi,'').toUpperCase()
  O.textContent=f(i)
}

update()
<input id=I value='BALLOON' oninput='update()' >
<pre id=O></pre>

3 comments
Justin Mariner 09/02/2017
You can replace the \n with a literal newline inside backticks for -1 byte.
edc65 09/02/2017
@JustinMariner no I can't, not inside the double quote in eval
Justin Mariner 09/02/2017
Oh right, that's a shame. My bad.

scottinet 09/03/2017.

C (gcc), 69 bytes

i;f(char*s){for(i=64;*s;putchar(*s^i?32:*s++))i+=i^90?1:puts("")-26;}

Try it online!


Kevin Cruijssen 09/04/2017.

Java 8, 161 159 bytes

s->{String x="",r=x;int p=0;for(char c:s)x+=p<(p=c)?c:";"+c;for(String y:x.split(";"))r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ\n".replaceAll("[^"+y+"\n]"," ");return r;}

-2 bytes thanks to @Nevay.

Explanation:"

Try it here.

s->{                          // Method with String as both parameter and return-type
  String x="",                //  Temp-String
         r=x;                 //  Result-String
  int p=0;                    //  Previous character (as integer)
  for(char c:s)               //  Loop (1) over the characters of the input
    x+=p<(p=c)?               //   If the current character is later in the alphabet
                              //   (replace previous `p` with current `c` afterwards)
        c                     //    Append the character to String `x`
       :                      //   Else:
        ";"+c;                //    Append a delimiter ";" + this character to String `x`
                              //  End of loop (1) (implicit / single-line body)
  for(String y:x.split(";"))  //  Loop (2) over the String parts
    r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"
                              //   Take the alphabet,
        .replaceAll("[^"+y+"\n]"," ");
                              //   and replace all except the characters with a space
                              //  End of loop (2) (implicit / single-line body)
  return r;                   //  Return the result-String
}                             // End of method

The first part of the method splits the input-word into parts with a delimiter.
For example: CODEGOLFCO;DEGO;L;F or BALLOONB;AL;LO;O;N.

The second part loops over these parts, and uses the regex [^...\n] to replace everything that isn't matched with a space.
For example .replaceAll("[^CO\n]"," ") leaves the C, O and new-line \n, and replaces everything else with a space.

2 comments
1 NieDzejkob 09/04/2017
Wouldn't it be B;AL;LO;O;N?
1 Nevay 09/04/2017
-2 bytes: for(char c:s)x+=p<(p=c)?c:";"+c;.

Halvard Hummel 09/02/2017.

Python 2, 92 bytes

f=lambda x,y=65:x and(y<=ord(x[0])and" "*(ord(x[0])-y)+x[0]+f(x[1:],-~ord(x[0]))or"\n"+f(x))

Try it online!

1 comments
1 ovs 09/02/2017

Justin Mariner 09/03/2017.

Japt, 18 16 bytes

-2 bytes thanks to @Shaggy

;ò¨ £B®kX ?S:Z
·

Uppercase input only.

Try it online!

Explanation

;

Switch to alternate variables, where B is the uppercase alphabet.

ò¨

Split the input string between characters where the first is greater than or equal to (¨) the second.

£

Map each partition by the function, where X is the current partition.

Map each character in the uppercase alphabet to the following, with Z being the current letter.

kX

Remove all letters in the current partition from the current letter. If the current letter is contained in the current partition, this results in an empty string.

?S:Z

If that is truthy (not an empty string), return a space (S), otherwise return the current letter.

·

Join the result of the previous line with newlines and print the result.

5 comments
ETHproductions 09/02/2017
10 bytes for r"[^{Z}]"S seems a bit ridiculous, but I can't find any better way either...
Shaggy 09/03/2017
Shaggy 09/03/2017
Justin Mariner 09/03/2017
@Shaggy Good thinking with kX!
ETHproductions 09/05/2017
Actually I think you can change kX ?S:Z to oX ªS to save two bytes

Dom Hastings 09/02/2017.

Perl 5, 44 bytes

40 bytes code + 4 for -lF.

print map/$F[0]/?shift@F:$",A..Z while@F

Try it online!

2 comments
ThePirateBay 09/02/2017
The link you've posted is for 46 bytes version.
Dom Hastings 09/02/2017
@ThePirateBay Thanks!! I knew I hadn't updated something!

Erik the Outgolfer 09/02/2017.

Pyth, 18 bytes

#pbVGp?JqhzNNd=>zJ

Try it here.

Leading newline in output, lowercase alphabet.


Luis Mendo 09/02/2017.

MATL, 24 23 bytes

''jt8+t1)wdh26X\Ys(26e!

Uses lowercase letters.

Try it at MATL Online!

Explanation

''     % Push empty string
jt     % Push input string. Duplicate
8+     % Add 8 to each char (ASCII code). This transforms 'a' 105,
       % 'b' into 106, which modulo 26 correspond to 1, 2 etc
t1)    % Duplicate. Get first entry
wd     % Swap. COnsecutive differences.
h      % Concatenate horizontally
26X\   % 1-based modulo 26. This gives a result from 1 to 26
Ys     % Cumulative sum
(      % Write values (converted into chars) at specified positions
       % of the initially empty string
26e    % Reshape into a 26-row char matrix, padding with char 0
!      % Transpose. Implicitly display. Char 0 is shown as space

Erik the Outgolfer 09/03/2017.

Jelly, 19 bytes

<2\¬0;œṗfȯ⁶$¥€@€ØAY

Try it online!

4 comments
Jonathan Allan 09/03/2017
OI<1®; -> >2\0; to save one byte (I actually did >2\0;œṗµØAf€ȯ€⁶µ€Y for 18 too, which I personally find easier to parse)
Erik the Outgolfer 09/03/2017
@JonathanAllan I think that would fail for BALLOON or something.
Jonathan Allan 09/03/2017
You are correct, yes - so it would required another byte with something like <2\1;¬; oh well.
Erik the Outgolfer 09/03/2017
@JonathanAllan Anyways, I'll implement your idea in my answer...done.

Jenny_mathy 09/02/2017.

Mathematica, 184 bytes

(t=Characters@#;s=Flatten@Table[Alphabet[],(l=Length)@t];q=1;For[i=1,i<=l@s,i++,If[s[[i]]!=t[[q]],s[[i]]=" ",q++];If[q>l@t,q--;t[[q]]=0]];StringRiffle[StringPartition[""<>s,26],"\n"])&

Justin Mariner 09/02/2017.

JavaScript (ES6), 87 bytes

f=([...s])=>s[0]?(g=i=>i>35?`
`+f(s):(i-parseInt(s[0],36)?" ":s.shift())+g(i+1))(10):""

Accepts uppercase or lowercase input. Output match the case of the input.

Tests

f=([...s])=>s[0]?(g=i=>i>35?`
`+f(s):(i-parseInt(s[0],36)?" ":s.shift())+g(i+1))(10):""

;O.innerText=["CODEGOLF","STACKEXCHANGE","F","ZYXWVUTSRQPONMLKJIHGFEDCBA","ANTIDISESTABLISHMENTARIANISM"]
.map(f).join("=".repeat(26)+"\n")
<pre id=O>


Neil 09/02/2017.

Retina, 130 bytes

$
¶ABCDEFGHIJKLMNOPQRSTUVWXYZ
+`(?<=(.)*)((.).*¶(?<-1>.)*(?(1)(?!)).+\3.*$)
 $2
(?<=(.)*)((.).*¶(?<-1>.)*(?<-1>\3.*$))
¶$2
}`¶.*$

Try it online! Explanation:

$
¶ABCDEFGHIJKLMNOPQRSTUVWXYZ

Append the alphabet.

+`(?<=(.)*)((.).*¶(?<-1>.)*(?(1)(?!)).+\3.*$)
 $2

Align as many letters as possible with their position in the alphabet.

(?<=(.)*)((.).*¶(?<-1>.)*(?<-1>\3.*$))
¶$2

Start a new line before the first letter that could not be aligned.

}`¶.*$

Delete the alphabet, but then do everything over again until there are no misaligned letters.

2 comments
Justin Mariner 09/02/2017
This seems to print only one line, not aligning letters on subsequent lines.
Neil 09/02/2017
@JustinMariner My bad, I made a typo in my last golf and failed to check it properly.

GolfWolf 09/03/2017.

Haskell, 81 74 73 bytes

q@(w:y)!(x:z)|w==x=x:y!z|1<2=min ' 'x:q!z
x!_=x
a=['A'..'Z']++'\n':a
(!a)

Saved 1 byte thanks to Laikoni!

Try it online.

Haskell Hugs optimizations

  1. The Hugs interpreter allows me to save one more byte by doing (!cycle$['A'..'Z']++"\n") instead of: (!cycle(['A'..'Z']++"\n")), but GHC does not like the former. (This is now obsolete; Laikoni already rewrote that line in a way that saved 1 byte.)

  2. Apparently, Hugs also does not require parentheses around the list pattern matcher, so I could save two more bytes going from: q@(w:y)!(x:z) to q@(w:y)!x:z.

4 comments
Laikoni 09/02/2017
You can save a byte with a=['A'..'Z']++'\n':a;(!a). Interesting to now that Hugs seems to have somewhat laxer rules.
GolfWolf 09/03/2017
@Laikoni I'm looking at Haskell for months now and it doesn't cease to amaze me. I love the a=...:a trick. Thanks!
Wheat Wizard 09/03/2017
I don't know if you are aware of this but I think its worth mentioning. The reason Hugs is different here is that there is lower operator precedence for user defined operators than in the ghc.
GolfWolf 09/03/2017
@WheatWizard I wasn't aware. This makes perfect sense, given the error I got in GHC.

FryAmTheEggman 09/03/2017.

Retina, 80 bytes

^
;¶
{`;.*
¶;ABCDEFGHIJKLMNOPQRSTUVWXYZ
¶¶
¶
)+`;(.*)(.)(.*¶)\2
$.1$* $2;$3
;.*

Try it online!

There is always exactly one leading newline. The code somewhat clunkily prepends the word with the alphabet along with a marker (semicolon). It then moves the marker up to the first letter of the word, while changing all other letters it passes into spaces. It also removes the first letter of the word. It repeats this until the first letter of the word isn't after the marker anymore. Then it clears that marker and the rest of the alphabet, and replaces it with a new line and the alphabet with a marker again. It keeps repeating this until the input word is empty, then it cleans up the last alphabet and marker, leaving the desired output.


Leaky Nun 09/02/2017.

Jelly, 24 21 bytes

3 bytes thanks to Erik the Outgolfer.

O64;I%26’⁶ẋЀ;"⁸Ẏs26Y

Try it online!

1 comments
7 Justin Mariner 09/02/2017
I believe this fails for input "BALLOON" - the repeated characters are on the same line.

dzaima 09/02/2017.

SOGL V0.12, 22 bytes

±E⁄Z*{@;eJι=?Xē}}¹∑z⁄n

Try it Here!


Zacharý 09/02/2017.

Dyalog APL, 47 37 34 bytes

{↑{⍵∘{⍵∊⍺:⍵⋄' '}¨⎕A}¨⍵⊂⍨1,2≥/⎕A⍳⍵}

Try it online!

How? (argument is )

  • ⍵⊂⍨1,2≥/⎕A⍳⍵, split into alphabetically ordered segments
  • {...}¨, apply this function to each letter (argument is ):
    • ⎕A, the alphabet
    • ...¨, apply this function to each argument (argument is ):
      • ⍵∘, pass in as the left argument () to the function:
        • {⍵∊⍺:⍵⋄' '}, if is in , then return , otherwise a space. This function is what creates a line of text.
  • , turn into an array (equivalent of adding the newlines)

JungHwan Min 09/03/2017.

Mathematica, 73 71 72 bytes

Print@@(Alphabet[]/.Except[#|##,_String]->" ")&@@@Split[#,Order@##>0&];&
(* or *)
Print@@@Outer[If[!FreeQ@##,#2," "]&,Split[#,Order@##>0&],Alphabet[],1];&

sacrificed a byte to fix the output

Takes a list of lower case characters (which is a "string" per meta consensus).

Try it on Wolfram Sandbox

Usage

f = (Print@@(Alphabet[]/.Except[#|##,_String]->" ")&@@@Split[#,Order@##>0&];&)

 

f[{"c", "o", "d", "e", "g", "o", "l", "f"}]
 c           o           
  de g       o           
          l              
    f                    
4 comments
2 Bill Steihn 09/03/2017
Your input is a list of strings? Is this valid?
1 Bill Steihn 09/03/2017
Also this outputs {Null, Null, Null, Null} at the end. Is this allowed by OP?
JungHwan Min 09/03/2017
@BillSteihn Yes, per meta consensus. For your second question, it prints the string to STDOUT. The Nulls are what the expression evaluates to, not a part of STDOUT (you can see this easily on Mathematica Kernel). For now, I fixed the issue by adding a byte.
JungHwan Min 09/03/2017
@BillSteihn the question specifies that a list of strings (i presume the list containing each line) is not a valid output format. I reckon it's fine as the input format, especially if it's a list of characters (plus, some languages have no distinction between a string and a list of characters, so disallowing this only makes the question unfair).

H.PWiz 09/03/2017.

Husk, 22 21 19 17 bytes

-2 bytes thanks to Zgarb (and a new language feature)

mȯΣẊṠ:ȯR' ←≠:'@ġ>

Try it online!

Explanation

               ġ>    Group into increasing sublists
mȯ                   To each sublist apply the following three functions
            :'@      ¹Append '@' (The character before 'A') to the start
   Ẋ                 ²Apply the following function to all adjacent pairs
           ≠            Take the difference of their codepoints
          ←             Minus 1
      ȯR'               Repeat ' ' that many times
    Ṡ:                  Append the second argument to the end.
  Σ                  ³concatenate
2 comments
Zgarb 09/02/2017
19 bytes with the new binary overloading of .
H.PWiz 09/02/2017
@Zgarb Wow fancy!

Josiah Winslow 09/03/2017.

Golfscript, 22 21 bytes

Try it online!

-1 byte thanks to careful final redefining of the n built-in.

{.n>{}{'
'\}if:n}%:n;

Explanation (with a slightly different version):

{.n>{}{"\n"\}if:n}%:n; # Full program
{                }%    # Go through every character in the string
 .n>         if        # If ASCII code is greater than previous...
                       # (n means newline by default, so 1st char guaranteed to fit)
    {}                 # Do nothing
      {"\n"\}          # Else, put newline before character
               :n      # Redefine n as the last used character
                   :n; # The stack contents are printed at end of execution
                       # Literally followed by the variable n, usually newline
                       # So because n is by now an ASCII code...
                       # ...redefine n as the new string, and empty the stack

streetster 09/04/2017.

q/kdb+, 48 bytes

Solution:

-1{@[26#" ";.Q.A?x;:;x]}@/:{(0,(&)x<=prev x)_x};

Examples:

q)-1{@[26#" ";.Q.A?x;:;x]}@/:{(0,(&)x<=prev x)_x}"STACKEXCHANGE";
                  ST
A C       K
    E                  X
  C    H
A            N
      G
    E
q)-1{@[26#" ";.Q.A?x;:;x]}@/:{(0,(&)x<=prev x)_x}"BALLOON";
 B
A          L
           L  O
              O
             N

Explanation:

Solution is split into two parts. First split the string where the next character is less than or equal to the current:

"STACKEXCHANGE" -> "ST","ACK","EX","CH","AN","G","E"

Then take a string of 26 blanks, and apply the input to it at the indices where the input appears in the alphabet, and print to stdout.

" " -> __________________ST______

Breakdown:

-1{@[26#" ";.Q.A?x;:;x]}each{(0,where x<=prev x)_x}; / ungolfed solution
-1                                                 ; / print to stdout, swallow return value
                            {                     }  / first lambda function
                                                _x   / cut (_) x at these indices
                             (                 )     / do this together
                                      x<=prev x      / is current char less-or-equal than previous?
                                where                / indices where this is true
                              0,                     / prepended with 0
                        each                         / take each item and apply function to it
  {                    }                             / second lambda function
   @[      ;      ; ; ]                              / apply[variable;indices;function;arguments]
     26#" "                                          / 26 take " " is "      "...
            .Q.A?x                                   / lookup x in the alphabet, returns indices
                   :                                 / assignment
                     x                               / the input to apply to these indices

scottinet 09/04/2017.

05AB1E, 18 bytes

ćIgµ¶?AvDyÊið?ë¼?ć

Try it online!

Got trouble with 05AB1E ć (extract 1) leaving an empty string/list on the stack after the last element is extracted. This solution would be 1-2 bytes shorter if it weren't for that.

ćIgµ¶?AvDyÊið?ë¼?ć  Implicit input 
ć                   Extract the 1st char from the string
 Igµ                While counter != length of the string
    ¶?              Print a newline
      Av            For each letter of the lowercased alphabet
        DyÊ         Is the examined character different from the current letter?
           ið?      If true, then print a space

              ë¼?ć  Else increment the counter, print the letter and push
                    the next character of the string on the stack
2 comments
Erik the Outgolfer 09/04/2017
Actually, ð, means "print a space and a newline".
scottinet 09/04/2017
You're right. Fixed the code to actually print a newline.

HighResolutionMusic.com - Download Hi-Res Songs

1 Alan Walker

Diamond Heart flac

Alan Walker. 2018. Writer: Alan Walker;Sophia Somajo;Mood Melodies;James Njie;Thomas Troelsen;Kristoffer Haugan;Edvard Normann;Anders Froen;Gunnar Greve;Yann Bargain;Victor Verpillat;Fredrik Borch Olsen.
2 Sia

I'm Still Here flac

Sia. 2018. Writer: Sia.
3 Cardi B

Taki Taki flac

Cardi B. 2018. Writer: Bava;Juan Vasquez;Vicente Saavedra;Jordan Thorpe;DJ Snake;Ozuna;Cardi B;Selena Gomez.
4 Little Mix

Woman Like Me flac

Little Mix. 2018. Writer: Nicki Minaj;Steve Mac;Ed Sheeran;Jess Glynne.
5 Halsey

Without Me flac

Halsey. 2018. Writer: Halsey;Delacey;Louis Bell;Amy Allen;Justin Timberlake;Timbaland;Scott Storch.
6 Lady Gaga

I'll Never Love Again flac

Lady Gaga. 2018. Writer: Benjamin Rice;Lady Gaga.
7 Bradley Cooper

Shallow flac

Bradley Cooper. 2018. Writer: Andrew Wyatt;Anthony Rossomando;Mark Ronson;Lady Gaga.
8 Bradley Cooper

Always Remember Us This Way flac

Bradley Cooper. 2018. Writer: Lady Gaga;Dave Cobb.
9 Kelsea Ballerini

This Feeling flac

Kelsea Ballerini. 2018. Writer: Andrew Taggart;Alex Pall;Emily Warren.
10 Mako

Rise flac

Mako. 2018. Writer: Riot Music Team;Mako;Justin Tranter.
11 Dewain Whitmore

Burn Out flac

Dewain Whitmore. 2018. Writer: Dewain Whitmore;Ilsey Juber;Emilio Behr;Martijn Garritsen.
12 Avril Lavigne

Head Above Water flac

Avril Lavigne. 2018. Writer: Stephan Moccio;Travis Clark;Avril Lavigne.
13 Khalid

Better flac

Khalid. 2018. Writer: Charlie Handsome;Jamil Chammas;Denis Kosiak;Tor Erik Hermansen;Mikkel Stoleer Eriksen;Khalid.
14 Lady Gaga

Look What I Found flac

Lady Gaga. 2018. Writer: DJ White Shadow;Nick Monson;Mark Nilan Jr;Lady Gaga.
15 Deep Chills

Run Free flac

Deep Chills. 2018.
16 Dynoro

In My Mind flac

Dynoro. 2018. Writer: Georgi Kay;Feenixpawl;Ivan Gough.
17 Charli XCX

1999 flac

Charli XCX. 2018. Writer: Charli XCX;Troye Sivan;Leland;Oscar Holter;Noonie Bao.
18 NCT 127

Regular (English Version) flac

NCT 127. 2018.
19 Lukas Graham

Love Someone flac

Lukas Graham. 2018. Writer: Don Stefano;Morten "Rissi" Ristorp;Morten "Pilo" Pilegaard;Jaramye Daniels;James Alan;David LaBrel;Lukas Forchhammer Graham.
20 Rita Ora

Let You Love Me flac

Rita Ora. 2018. Writer: Rita Ora.

Related questions

Hot questions

Language

Popular Tags