57
\$\begingroup\$

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!
\$\endgroup\$
9
  • \$\begingroup\$ Are leading newlines allowed? \$\endgroup\$ Sep 2, 2017 at 13:46
  • \$\begingroup\$ @EriktheOutgolfer Sure, as long as it doesn't mess up grid structure. \$\endgroup\$
    – shooqie
    Sep 2, 2017 at 13:49
  • \$\begingroup\$ Would it be okay if a non-fatal error stops the program? \$\endgroup\$
    – Adalynn
    Sep 2, 2017 at 21:07
  • \$\begingroup\$ @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. \$\endgroup\$
    – shooqie
    Sep 2, 2017 at 21:09
  • 8
    \$\begingroup\$ Suggested test case: BALLOON (two adjacent characters that are the same). \$\endgroup\$ Sep 4, 2017 at 12:37

46 Answers 46

1
2
1
\$\begingroup\$

R, 95 bytes

Just run through the upper case alphabet repeatedly while advancing a counter by 1 if you encounter the letter in the counter position of the word and printing out the letter, a space otherwise.

function(s)while(F>""){for(l in LETTERS)cat("if"((F=substr(s,T,T))==l,{T=T+1;l}," "));cat("
")}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

GolfScript, 37 bytes

64:a;{.a>{}{'
'\64:a;}if.a-(' '*\:a}%

Try it online!

I did a Golfscript one under a different name, but it had incorrect output.

\$\endgroup\$
1
\$\begingroup\$

Ruby -n, 62 bytes

Scans the input string for sequences of increasing letters, and for each sequence, replace letters not in the sequence with spaces.

g=*?A..?Z
$_.scan(/#{g*??}?/){puts g.join.tr"^#$&"," "if$&[0]}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 21 19 17 bytes

Çü@0šÅ¡vð₂×yAykǝ,

Try it online!

Ç       push a list of ascii values of the input        [84, 69, 83, 84]
ü@      determine which letter is >= the next letter    [1, 0, 0]
0š      prepend a 0 (false) to that list                [0, 1, 0, 0]
Å¡      split input on true values                      [["T"], ["E", "S", "T"]]
v       for each list entry
  ð₂×     push 26 spaces
  y       push list entry (letters)
  Ayk     push the positions of that letters in the alphabet
  ǝ       replace characters c in string a with letters b
  ,       print the resulting string
        implicitly close for-loop
\$\endgroup\$
1
\$\begingroup\$

Zsh, 67 bytes

-4 bytes thanks to @pxeger

for ((;#1;))echo&&for y ({A..Z})printf ${(Ml:1:)1[1]%$y}&&1=${1#$y}

Try it online! Try it online!

Append to $s a (M) matched letter, (l:1:) left-padded to one character, then remove the letter if it matches the start of $1.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ -4 on the second solution: Try it online! \$\endgroup\$
    – pxeger
    May 11, 2021 at 12:29
  • \$\begingroup\$ Rules don't permit leading spaces, but nice 3 byte save \$\endgroup\$ May 11, 2021 at 19:34
  • \$\begingroup\$ It is allowed: "Are leading newlines allowed?" -- "Sure, as long as it doesn't mess up grid structure." \$\endgroup\$
    – pxeger
    May 12, 2021 at 6:51
  • \$\begingroup\$ Ah, I didn't read the comments, just the main post. \$\endgroup\$ May 12, 2021 at 11:37
0
\$\begingroup\$

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)
\$\endgroup\$
0
\$\begingroup\$

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                    
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Your input is a list of strings? Is this valid? \$\endgroup\$
    – user73398
    Sep 3, 2017 at 0:00
  • 1
    \$\begingroup\$ Also this outputs {Null, Null, Null, Null} at the end. Is this allowed by OP? \$\endgroup\$
    – user73398
    Sep 3, 2017 at 0:16
  • \$\begingroup\$ @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. \$\endgroup\$ Sep 3, 2017 at 0:26
  • \$\begingroup\$ @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). \$\endgroup\$ Sep 3, 2017 at 0:42
0
\$\begingroup\$

><>, 63 bytes

d5*v
(?;\i:0
~{?\}::{::}@=::{$" ["a${=:}?$~@?$~o10d2*-{?$~{+}}?

Try it online!

Input is expected in uppercase.

\$\endgroup\$
0
\$\begingroup\$

Kotlin, 133 131 129 bytes

fun r(s:String){var c=0
while(0<1){('A'..'Z').map{if(c==s.length)return
if(s[c]==it){print(s[c])
c++}else print(" ")}
println()}}

Try it online!

Explained

fun r(s: String) {
    // Current character
    var c = 0
    // Keep going until the end of the string
    while (0 < 1) {
        // Go through the letters
        ('A'..'Z').map{
            // If the word is done then stop
            // Have to check after each letter
            if (c == s.length) return
            // If we are at the right letter
            if (s[c] == it) {
                // Print it
                print(s[c])
                // Go to the next letter
                c++
            // Otherwise print space
            } else print(" ")
        }
        // Put a newline between the lines
        println()
    }
}

Test

fun main(args:Array<String>)=r("CODEGOLF")

Edit: Ran through my compressor, saved 2 bytes.

\$\endgroup\$
0
\$\begingroup\$

C++, 202 197 bytes

-5 bytes thanks to Zacharý

#include<iostream>
#include<string>
using c=std::string;void f(c s){std::cout<<c(s[0]-65,32)<<s[0];for(int i=1;i<s.size();++i)std::cout<<(s[i]>s[i-1]?c(s[i]-s[i-1]-1,32):"\n"+c(s[i]-65,32))<<s[i];}
\$\endgroup\$
2
  • \$\begingroup\$ I think (s[i]>s[i-1])=>s[i]>s[i-1] works, along with moving the int i=1 to the for-loop. \$\endgroup\$
    – Adalynn
    Sep 9, 2017 at 14:27
  • \$\begingroup\$ Also, ("\n"+c(s[i]-65,32)) => "\n"+c(s[i]-65,32) \$\endgroup\$
    – Adalynn
    Sep 9, 2017 at 14:32
0
\$\begingroup\$

PHP, 121 bytes

<?$p=$argv[1];$b=substr;while($p){for($i=A;$i!=AA;$i++){if($p[0]==$i){echo$b($p,0,1);$p=$b($p,1);}else echo" ";}echo'
';}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Kotlin, 101 bytes

Port of the Powershell.

{s:String->var p=' '
var x=""
var r=""
s.map{c->if(c<p){r+=x+"\n";x=""}
x=x.padEnd(c-'A')+c
p=c}
r+x}
\$\endgroup\$
0
\$\begingroup\$

Rust, 163 bytes

|s:&str|{let mut s=s.bytes().peekable();while s.peek().is_some(){for c in 65..91{print!("{}",if Some(c)==s.peek().cloned(){s.next();c}else{32}as char)}println!()}}

Try it online!

Explanation

|s:&str|{                                        // Take a single parameter s (a string)
  let mut s=s.bytes().peekable();                // Turn s into a peekable iterator
  while s.peek().is_some(){                      // While s is nonempty:
    for c in 65..91{                             //   For every c in range [65, 91) (uppercase alphabet):
      print!("{}",if Some(c)==s.peek().cloned(){ //     If the next character in s is the same as c:
        s.next();                                //       Advance the iterator
        c                                        //       Print c as a character
      } else {                                   //     Else:  
        32                                       //       Print a space
      } as char)                                 //
    }                                            //
    println!()                                   //   Print a newline
  }
}
\$\endgroup\$
0
\$\begingroup\$

Stax, 12 bytes

ü→Δe-Y─▲99╣w

Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

{<!}    block tests if one value is >= another
)       use block to split input into partitions by testing adjacent pairs
m       map partitions using rest of the program and output
  zs    put a zero-length array under the partition in the stack
  F     for each letter in the array, run the rest of the program
    65- subtract 65 (ascii code for 'A')
    _&  set the specified index to the character, extending the array if necessary

Run this one

\$\endgroup\$
0
\$\begingroup\$

Japt -R, 11 bytes

;ó< £BôkX ¸

Try it or run all test cases

;ó< £BôkX ¸     :Implicit input of string
 ó<             :Partition between characters where the first is < the second
    £           :Map each X
;    B          :  Uppercase alphabet
      ô         :  Split at characters that return falsey (empty string)
       kX       :    When the characters in X are removed
          ¸     :  Join with spaces
                :Implicit output joined with newlines
\$\endgroup\$
-1
\$\begingroup\$

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"])&
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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