使单词适合字母网格


55

受到我今天早些时候看到的一个模因的启发。

挑战说明

考虑一个无限的字母网格:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZ
...

取一个单词(CODEGOLF在此示例中)并使其成为网格的子序列,用空格替换未使用的字母,并在无限网格的末尾完全删除字母:

  C           O           
   DE G       O           
           L              
     F

例子

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

笔记

  • 允许尾随空格。
  • 您无需在空格的最后一行填充空格。例如,如果输入为ABC,则可以输出ABC不带23个尾随空格的输出。
  • 您可以假设输入将匹配[A-Z]+正则表达式。
  • 或者,您可以使用小写字母,在这种情况下输出将匹配[a-z]+
  • 您必须使用一个换行符(\n\r\n或相当于)来分隔行,这是一个字符串列表不正确的输出格式。
  • 这是一个挑战,所以请使您的代码尽可能短!

允许换行符吗?
Erik the Outgolfer '17

@EriktheOutgolfer当然,只要它不会弄乱网格结构即可。
shooqie

如果非致命错误停止了程序,可以吗?
扎卡里

@Zacharý尽管我可以看到如何节省一些字节,但我认为它很丑陋,并且会产生不需要的多余输出。所以不行。编辑:除非您可以使程序通过退出代码或不会打印异常堆栈跟踪的东西或类似于stderr的东西非致命地退出。
shooqie

7
建议的测试用例:(BALLOON两个相同的相邻字符)。
凯文·克鲁伊森

Answers:


10

外壳,15个字节

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

在线尝试!

说明

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.

7

爪哇10,161个 159 152字节

s->{var x="";int p=0;for(var c:s)x+=p<(p=c)?c:";"+c;for(var y:x.split(";"))System.out.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ".replaceAll("[^"+y+"]"," "));}

-2个字节,感谢@Nevay
直接打印-7字节而不是返回字符串,然后转换为Java 10。

说明:

在这里尝试。

s->{                      // Method with String parameter and no return-type
  var x="";               //  Temp-String
  int p=0;                //  Previous character (as integer), starting at 0
  for(var 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 current character to Temp-String `x`
       :                  //   Else:
        ";"+c;            //    Append a delimiter ";" + this character to Temp-String `x`
  for(var y:x.split(";")) //  Loop (2) over the String-parts
    System.out.println(   //   Print, with trailing new-line:
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                          //    Take the alphabet,
        .replaceAll("[^"+y+"]"," "));}
                          //    and replace all letters not in the String-part with a space

该方法的第一部分使用分隔符将输入字分割为多个部分。
例如:CODEGOLFCO;DEGO;L;FBALLOONB;AL;LO;O;N

第二部分遍历这些部分,并使用正则表达式[^...]替换与空格不匹配的所有内容。
例如,.replaceAll("[^CO]"," ")保留C,和O,并用空格替换其他所有内容。


1
不是B;AL;LO;O;N吗?
NieDzejkob

1
-2个字节:for(char c:s)x+=p<(p=c)?c:";"+c;
Nevay




4

JavaScript(ES6),79

编辑因为接受了换行符,所以我可以保存2个字节

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

再增加1个字节,我可以接受小写或大写输入:

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

少打高尔夫球

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
}  

测试

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>


您可以将\n反引号内的文字换行符替换为-1字节。
贾斯汀·马里纳

@JustinMariner不,我不能,不在eval的双引号内
edc65'9

哦,对,真可惜。我的错。
贾斯汀·马里纳

4

MATL24 23字节

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

使用小写字母。

MATL在线上尝试一下

说明

''     % 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

4

Japt18 16字节

-2个字节,感谢@Shaggy

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

仅大写输入。

在线尝试!

说明

;

切换到备用变量,这里B是大写字母。

ò¨

将输入字符串分隔在第一个大于或等于(¨)第二个的字符之间。

£

通过函数映射每个分区,X当前分区在哪里。

将大写字母中的每个字符映射为以下字母,并将Z其作为当前字母。

kX

从当前字母中删除当前分区中的所有字母。如果当前字母包含在当前分区中,则结果为空字符串。

?S:Z

如果这是事实(不是空字符串),请返回一个空格(S),否则返回当前字母。

·

用换行符将前一行的结果连接起来并打印结果。


10个字节r"[^{Z}]"S似乎有点荒谬,但我也找不到更好的方法……
ETHproductions



@Shaggy好思想kX
贾斯汀·马里纳

实际上,我认为您可以更改kX ?S:ZoX ªS节省两个字节
ETHproductions's


3

果冻,19字节

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

在线尝试!


OI<1®;-> >2\0;保存一个字节(我实际上也做>2\0;œṗµØAf€ȯ€⁶µ€Y了18 个字节,我个人觉得比较容易解析)
Jonathan Allan

@JonathanAllan我认为这可能会失败BALLOON
Erik the Outgolfer '17

您是正确的,是的-因此它需要另一个字节,例如<2\1;¬; 那好吧。
乔纳森·艾伦,

@JonathanAllan无论如何,我会在我的回答中实现您的想法...完成。
Erik the Outgolfer


3

Mathematica,101个字节

StringRiffle[
  Alphabet[]/.#->" "&/@
   (Except[#|##,_String]&@@@
     Split[Characters@#,#==1&@*Order]),"
",""]&

Split输入严格增加的字母序列,将相邻的字母与进行比较Order。如果为Order[x,y] == 1,则在字母x前面y,因此可以出现在同一行上。

对于每个字母序列,创建一个模式以匹配Except这些字母的字符串;#|##是的简写Alternatives。将Alphabet与模式匹配的字母替换为空格。


中间步骤的图示:

"codegolf";
Split[Characters@#,#==1&@*Order]  &@%
Except[#|##,_String]&@@@         #&@%
Alphabet[]/.#->" "&/@               %
{{"c", "o"}, {"d", "e", "g", "o"}, {"l"}, {"f"}}

{Except["c" | "c" | "o", _String], 
 Except["d" | "d" | "e" | "g" | "o", _String], 
 Except["l" | "l", _String],
 Except["f" | "f", _String]}

{{" "," ","c"," "," "," "," "," "," "," "," "," "," "," ","o"," "," "," "," "," "," "," "," "," "," "," "},
 {" "," "," ","d","e"," ","g"," "," "," "," "," "," "," ","o"," "," "," "," "," "," "," "," "," "," "," "},
 {" "," "," "," "," "," "," "," "," "," "," ","l"," "," "," "," "," "," "," "," "," "," "," "," "," "," "},
 {" "," "," "," "," ","f"," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "}}

2

Golfscript,22 21字节

在线尝试!

-1个字节,这要归功于n内置组件的精心重新定义。

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

说明(版本略有不同):

{.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

2

视网膜,80字节

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

在线尝试!

总有一条领先的换行符。该代码有些笨拙地在单词前加上了字母和标记(分号)。然后,它将标记移至单词的第一个字母,同时更改所有其他传递到空格的字母。它还会删除单词的第一个字母。重复此操作,直到单词的第一个字母不再位于标记之后。然后,清除该标记和字母的其余部分,并用新行替换它,并再次用标记替换字母。它会不断重复此操作,直到输入单词为空,然后清除最后一个字母和标记,留下所需的输出。


2

05AB1E,18个字节

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

在线尝试!

遇到麻烦,因为05AB1E ć(提取1)在提取最后一个元素后在堆栈上留下了空字符串/列表。如果不是这样,该解决方案将短1-2个字节。

ć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

实际上,ð,意思是“打印空格和换行符”。
暴民埃里克(Erik the Outgolfer)

你是对的。修复了代码实际打印换行符的问题。
scottinet

2

视网膜130个 126字节

$
¶A
{-2=`
$'
}T`RL`_o`.$
+`(?<=(.)*)((.).*¶(?<-1>.)*(?(1)(?!)).+\3.*$)
 $2
(?<=(.)*)((.).*¶(?<-1>.)*(?<-1>\3.*$))
¶$2
}`¶.*$

在线尝试!编辑:使用@MartinEnder的字母生成器保存了4个字节。说明:

$
¶A
{-2=`
$'
}T`RL`_o`.$

附加字母。

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

将尽可能多的字母与其在字母表中的位置对齐。

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

在无法对齐的第一个字母之前开始新的一行。

}`¶.*$

删除字母,然后再次进行所有操作,直到没有未对齐的字母。


这似乎只打印一行,而不在后续行上对齐字母。
贾斯汀·马里纳

@JustinMariner我不好,我上次打高尔夫球时打错了打字,但未能正确检查。
尼尔

2

q / kdb +48 45字节

解:

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

在线尝试!

注意:链接到此解决方案的K(oK)端口,因为q / kdb +没有TIO。

例子:

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

q)-1{@[26#" ";.Q.A?x;:;x]}@/:(0,(&)(<=':)x)_x:"BALLOON";
 B
A          L
           L  O
              O
             N

说明:

Q从右到左解释。解决方案分为两部分。首先分割下一个字符小于或等于当前字符的字符串:

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

然后取一个由26个空格组成的字符串,并将输入应用到输入出现在字母中的索引处,并打印到stdout。

"__________________________" -> __________________ST______

分解:

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

笔记:

  • 通过用K4版本替换prev来-3字节

2

Powershell,70 63字节

-7个字节,谢谢@Veskah

$args|%{if($_-le$p){$x;rv x}
$x=("$x"|% *ht($_-65))+($p=$_)}
$x

在线尝试!

说明:

对于splatted参数中的每个字符:

  • 如果当前字符的代码小于或等于前一个字符的代码(),则输出字符串$x和清除$x值(Remove-Variable的rv别名)。-le
  • 将空格和当前字符附加到$x,并将其存储到中$x。它还会刷新以前的字符值。

最后输出$x


1
使用splatting的63个字节。试图用来|% *ht保存一些字节,但看起来它甚至收支平衡。
Veskah



1

JavaScript(ES6),87个字节

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

接受大写或小写输入。输出匹配输入的大小写。

测验


1

Haskell,81 74 73字节

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

感谢Laikoni节省了1个字节!

在线尝试。

Haskell Hugs优化

  1. Hugs解释器允许我通过执行以下操作来节省一个字节(!cycle$['A'..'Z']++"\n")(!cycle(['A'..'Z']++"\n"))但是GHC不喜欢前者(现在已过时; Laikoni已经以节省1个字节的方式重写了该行。)

  2. 显然,拥抱也不需要周围的列表模式匹配括号,这样我就可以节省两个字节从去:q@(w:y)!(x:z)q@(w:y)!x:z


您可以使用保存一个字节a=['A'..'Z']++'\n':a;(!a)。有趣的是,拥抱似乎似乎有一些宽松的规则。
Laikoni

@Laikoni我正在看Haskell几个月了,它并没有使我惊奇。我喜欢这个a=...:a把戏。谢谢!
Cristian Lupascu

我不知道您是否意识到这一点,但我认为值得一提。Hugs与此处不同的原因是,用户定义的运算符的运算符优先级低于ghc。
小麦巫师

@WheatWizard我不知道。考虑到我在GHC中遇到的错误,这完全有道理。
Cristian Lupascu



1

木炭,15字节

Fθ«J⌕αι⁺ⅉ‹⌕αιⅈι

在线尝试!链接是详细版本的代码。说明:

 θ              Input string
F «             Loop over characters
     α     α    Uppercase letters predefined variable
      ι     ι   Current character
    ⌕     ⌕     Find index
             ⅈ  Current X co-ordinate
         ‹      Compare
        ⅉ       Current Y co-ordinate
       ⁺        Sum
   J            Jump to aboslute position
              ι Print current character


1

K(ngn / k)29 28字节

{{x@x?`c$65+!26}'(&~>':x)_x}

在线尝试!

{ } 带参数的功能 x

>':x 对于每个字符,它是否大于先前的字符?

~ 否定

& 我们在哪里(在哪些指数处)为真

( )_xx在这些索引处剪切,返回字符串列表

{ }' 对于每个字符串

`c$65+!26

英文字母

x?在中找到每个字母的第一个出现的索引,如果找不到x,请使用0N(特殊的“ null”值)

x@指数x与; 索引与0N回报" ",所以我们得到了一个长度为26的字符串中从字母x都在他们的字母位置和其他一切都是空间


1

R129117字节

function(s){z={}
y=diff(x<-utf8ToInt(s)-64)
z[diffinv(y+26*(y<0))+x[1]]=LETTERS[x]
z[is.na(z)]=" "
write(z,1,26,,"")}

在线尝试!

说明(无胶体):

function(s){
 z <- c()                  # initialize an empty vector
 x <- utf8ToInt(s)-64      # map to char code, map to range 1:26
 y <- diff(x)              # successive differences of x
 idx <- cumsum(c(          # indices into z: cumulative sum of:
    x[1],                  # first element of x
    ifelse(y<=0,y+26,y)))  # vectorized if: maps non-positive values to themselves + 26, positives to themselves
 z[idx] <- LETTERS[x]      # put letters at indices
 z[is.na(z)] <- " "        # replace NA with space
 write(z,"",26,,"")        # write z as a matrix to STDOUT ("") with 26 columns and empty separator.

1

R,95字节

如果在单词的反位置遇到字母并打印出字母,则只需将大写字母反复运行,同时将计数器加1即可,否则打印空格。

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

在线尝试!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.