做一碗字母汤


55

这就是我们所说的一碗字母汤-一种大致呈圆形的ascii-art形状,具有26个大写英文字母(AZ)顺时针排列以形成周长:

   XYZABC
 VW      DE
U          F
T          G
S          H
 RQ      JI
   PONMLK

编写一个使用单个字母字符AZ并输出相同碗的“旋转”字母汤的程序,可以这么说,因此输入字母出现A在上例中的位置,其余字母完全循环顺时针。

因此,输入的输出A将是相同的原始碗字母汤。

输入的输出B将是以下内容:

   YZABCD
 WX      EF
V          G
U          H
T          I
 SR      KJ
   QPONML

同样,输出为H

   EFGHIJ
 CD      KL
B          M
A          N
Z          O
 YX      QP
   WVUTSR

Z

   WXYZAB
 UV      CD
T          E
S          F
R          G
 QP      IH
   ONMLKJ

这需要适用于从A到Z的所有26个字母。

细节:

  • 您可以假设唯一的输入将是单个字母,即A到Z。
  • 如果方便,可以将小写字母az用于输入和/或输出,甚至可以混合使用小写和大写字母。
  • 字母顺序必须顺时针循环,而不是逆时针循环。
  • 您必须使用空格而不是其他空格来缩进并填满汤碗。
  • 只要汤碗布置正确,输出中可能会有前导或尾随的换行符或空格。
  • 请注意,碗形的宽度为12个字符,宽为7个高,使它看起来像文本一样大致呈圆形。您的碗必须具有相同的形状。

这是代码高尔夫球,所以最短的代码获胜!


12
巨大的挑战!最初似乎很容易,但事实并非如此
Luis Mendo

Answers:


22

05AB1E,21字节

定义程序F字母字符

码:

2AA¹k._•1못*Ć,ãiDΣ•Λ

在线尝试!


分解:

2AA¹k._•1못*Ć,ãiDΣ•Λ

2                       # <length>
 AA¹k._                 # <filler>
       •1못*Ć,ãiDΣ•    # <pattern>
                    Λ   # Invoke the canvas function.


说明:

在此特定上下文中,canvasΛ)用作具有以下签名的函数:

Λ长度纳特 填料 图案纳特

在这种情况下,图案参数是定义方向的数字。在代码中,此数字表示为•1못*Ć,ãiDΣ•,它是大数字2232344565666667670012122的压缩版本。方向以以下方式表示:


701个62543


这意味着大数字代表以下方向模式:

[]

使用此签名上下文,画布将遍历图案列表,并沿当前方向从填充符写入长度字符。填料

长度在代码中指定为2(在代码开头)。对于填料,我们需要字母的旋转版本,使其以给定的输入开头。这是通过以下代码完成的(在此处尝试):

AA¹k._

 A¹k#在字母表中找到给定输入字符的<index>
._#将字母向左旋转<index>次。

用伪代码,这将由canvas函数执行:

1。写 b 在这个方向上2。写 公元前 在这个方向上3。写 光盘 在这个方向上4。写  在这个方向上5,写 ef 在这个方向上6。写 fg 在这个方向上

最后,您可以看到填充器参数的长度-1个是“旋转” 长度 -向右1倍,这意味着画布将遍历以下(循环的,因此是无限的)列表:

[b公元前光盘effggh你好ijk

这样就产生了所需的字母汤形艺术风格。


好吧,我放弃。试图找到更短的选择,但我没有看到它。AA¹k._也可以是A¹¡RJ«,但是它是相同的字节数。•1못*Ć,ãiDΣ•也可以是•õÕ₆qηµñ–†f•·,但是它是相同的字节数。呃,好吧。好答案!
凯文·克鲁伊森

11

Perl 6,100字节

{"2XYZABC
 VW5DE
U9F
T9G
S9H
 RQ5JI
2PONMLK".trans(/\S/=>{(try ' 'x$/+1)||chr ($/.ord+.ord)%26+65})}

在线尝试!

用移动的对等字母替换字符串中的所有字母,同时用表示的空格数加1替换数字。

说明

{                                                            }# Anonymous code block
 "...".trans(/\S/=>{                                       }) # Translate non-whitespace
                    (try ' 'x$/+1)      # If digits, the amount of spaces plus one
                                  ||chr ($/.ord+.ord)%26+64  # Else the shifted letter

9

红宝石,107字节

->n{a=(0..6).map{' '*11}
(?A..?Z).map{|i|j,k=(1i**((i.ord-n.ord-6)/6.5)).rect;a[3.5*k+=1][5.2*j+6]=i}
a*$/}

在线尝试!

改进的语法"i".to_c-> 1i(由约旦建议)

更改了坐标系,因此0度在右侧而不是顶部。这将启用0.5->6

调整后的乘数jk对困难

而不是输出输出puts a,而是连接数组元素并返回一个字符串a*$/

红宝石,119字节

->n{a=(0..6).map{' '*11}
(?A..?Z).map{|i|j,k=("i".to_c**((i.ord-n.ord+0.5)/6.5)).rect;a[3.5-j*3.3][6+k*5.17]=i}
puts a}

使用提高到幂的复数来映射到椭圆。一个完整的匝为26,因此每个象限为6.5。

该方法依赖于所需的输出,该输出足够类似于椭圆,从而可以实现有效的映射。

在线尝试!


@Jordan谢谢,我之前没有看过这种语法!
圣玛尔河

8

木炭,33字节

GH→→↘→↘↓↓77←←←←↖←↖↑↑↗→↗→→²✂⁺αα⌕αS

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

GH

追踪路径。

→→↘→↘↓↓77←←←←↖←↖↑↑↗→↗→→

勾勒出碗的轮廓。每个7扩展到↙←

²

一次移动一个字符(此API与每行的结尾与下一行重叠)。

✂⁺αα⌕αS

使用加倍的字母绘制,但从输入字符的位置开始。


8

MATL,49字节

7I8*32tvB[1b]&Zvc2Y2j7+_YSy&f7-w4-_Z;YPE\,&S])yg(

真是一团糟。但这很有趣。甚至涉及反正切。

在线尝试!

说明

编码

7I8*32tvB

创建一个数字数组并将其转换为二进制。这给出了零一矩阵

0 0 0 1 1 1
0 1 1 0 0 0
1 0 0 0 0 0
1 0 0 0 0 0

它是指定字母位置的矩阵的左上象限。

[1b]&Zv

垂直反射该象限,而不重复最后一行,水平反射最后一列以产生完整的矩阵:

0 0 0 1 1 1 1 1 1 0 0 0
0 1 1 0 0 0 0 0 0 1 1 0
1 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 1
0 1 1 0 0 0 0 0 0 1 1 0
0 0 0 1 1 1 1 1 1 0 0 0

现在,我们有了带有位置的蒙版。编码

c

将其转换为char,因为最终结果将是char矩阵。字符0显示为空格,非零条目将以适当的字母书写。

2Y2

推送'abc···xyz'包含26个字母的字符串。该字符串需要根据输入进行循环移位。要做到这一点,

j7+_YS

读取输入字母,在其ASCII码中加7,然后取反。对于输入,'a'这给出的是-104,它是26的倍数,因此循环移位此量将无济于事。如果输入b为-105,则将字符串向左移动1步以产生'bcd···yza'; 等等

下一步是定义将移位后的字符串写入矩阵的非零条目的顺序。为此,

y&f

创建矩阵的副本,并推入两个包含非零的基于1的行和列位置的向量。然后

7-w4-_

从后者减去7,将前者推到顶部,从中减去4,然后取反。7和4指定坐标的原点,以便非零项的位置矢量相对于该原点的角度定义所需的顺序。

Z;YPE\

计算两个参数的反正切模2 * pi以产生那些角度。现在最小的角度为0,对应于第一个字母应进入的条目,其余的则逆时针前进。

,&S])

根据这些角度重新排列字符串中的字母,以便当按列优先顺序(从下到下)将字母写入矩阵的非零条目时,结果将是正确的。这是通过

yg(

例如,如果输入是'a'字符串,则不会循环移位:

abcdefghijklmnopqrstuvwxyz

按照角度重新排列将其转换为

utsvrwqxpyoznamblckdjeifgh

这样就'u'可以正确地转到第一个(以列为主的顺序)非零条目,即矩阵表示法中的(3,1);'t'将转到(4,1),'s'到(5,1); 'v'至(2,2)等:

   ······   
 v·      ·· 
u          ·
t          ·
s          ·
 ··      ·· 
   ······   

@EriktheOutgolfer我终于找到了一些时间来补充说明
Luis Mendo

1
哇...我实际上以为您放弃了此评论,因为您删除了该评论。:P
暴民埃里克


7

R139122字节

-17字节归功于Giuseppe

u=utf8ToInt;`*`=rep;o=c(' '*12,'
')*7;o[u("  &3@LKWVUTSRDC5(")]=LETTERS[(13:38+u(scan(,'')))%%26+1];cat(o,sep='')

说明:

o=rep(c(rep(' ',12),'
'),7) 

建立一个空的空格框

u(" &3@LKWVUTSRDC5(")

是字母位置的一组索引,对应于:

c(7:9,23,24,38,51,64,76,75,87:82,68,67,53,40,27,15,16,4:6)

蒂奥


1
您永远不会使用,intToUtf8所以这些都是多余的字节,但是如果使用*代替rep,您可以节省2个字节,最多获取125个字节
Giuseppe

1
哦,使用低字节字符代替可打印的ascii,您可以删除-32 122个字节。您可以使用自己生成它们cat(intToUtf8(bytes))
朱塞佩

@Giuseppe我敢肯定我已经删除了intToUtf8,我猜想一次打开了太多版本的函数。尼斯节省了一切,谢谢
亚伦·海曼

6

的JavaScript(Node.js的) 121个  119字节

@tsh节省了2个字节

c=>`2XYZABC
0VW5DE
U9F
T9G
S9H
0RQ5JI
2PONMLK`.replace(/./g,x=>''.padEnd(+x+1)||(B=Buffer)([65+([a,b]=B(c+x),a+b)%26]))

在线尝试!

怎么样?

BufferXC

示例C="H"X="B"

// extracting the ASCII codes
Buffer(c + x)  Buffer("HB")  <Buffer 48 42>

// assigning them to variables
[a, b] = Buffer(c + x)  a = 0x48 (72) and b = 0x42 (66)

// computing the ASCII code of the target letter
65 + ((a + b) % 26)  65 + (138 % 26)  65 + 8  73

// turning it back into a character
Buffer([73])  <Buffer 49>  implicitly coerced to "I" by replace()



4

[R 218个 197字节

-21字节归功于Giuseppe

function(t,l=letters,`*`=rep,s=" ",n="
",`~`=`[`,r=c(l~l>=t,l))cat(s*3,r~24:26,r~1:3,n,s,r~22:23,q<-s*6,r~4:5,n,r~21,u<-s*10,r~6,n,r~20,u,r~7,n,r~19,u,r~8,n,s,r~17:18,q,r~10:9,n,s*3,r~16:11,sep='')

在线尝试!

取消高尔夫:

alphasoup <- function(startlet){
  startnum <- which(l == startlet)
  rotatedletters <- c(letters[startnum:26], letters[1:(startnum -1)])[1:26]
  cat('   ',rotatedletters[24:26],rotatedletters[1:3], '\n ', 
      rotatedletters[22:23], s6 <- '      ', rotatedletters[4:5], '\n',
      rotatedletters[21], s10 <- rep(' ', 10), rotatedletters[6], '\n',
      rotatedletters[20], s10, rotatedletters[7], '\n',
      rotatedletters[19], s10, rotatedletters[8], '\n ',
      rotatedletters[17:18], s6, rotatedletters[10:9], '\n   ',
      rotatedletters[16:11],
      sep = '')
}

创建旋转的字母矢量,并使用cat该矢量填充碗的边缘。


203字节(如果您不介意单行怪物);最大的改进可能是删除which并将l>=t其直接用作索引,该索引值12个字节。
朱塞佩

2
别名[198个字节~。这是一个很好的答案。在最初的几次尝试中,我花费了大约250个字节,并且使用了更为复杂的方法。
朱塞佩

啊,那很聪明,我忘了字符串比较。
CT大厅

3

Java 11,134字节

c->"2XYZABC_0VW5DE_U9F_T9G_S9H_0RQ5JI_2PONMLK".chars().forEach(i->System.out.print(i<59?" ".repeat(i-47):(char)(i>90?10:(c+i)%26+65)))

在线尝试。

136字节版本是否具有打高尔夫球的潜力?

c->"2XYZABC_0VW5DE_U9F_T9G_S9H_0RQ5JI_2PONMLK".chars().forEach(i->System.out.printf("%"+(i<59?i-47:"")+"c",i>90?10:i<59?32:(c+i)%26+65))

在线尝试。

说明(第一个答案)

c->                          // Method with character parameter and no return-type
  "2XYZABC_0VW5DE_U9F_T9G_S9H_0RQ5JI_2PONMLK"
                             //  Template-String
    .chars().forEach(i->     //  Loop over the unicode values of its characters:
    System.out.print(        //   Print:
     i<59?                   //    If the value is below 59 (so a digit character):
      " ".repeat(i-47)       //     Repeat a space that digit + 1 amount of times
     :(char)(i>90?           //    Else-if the value is above 90 (an underscore character):
              10             //     Print a newline
             :               //    Else:
              (c+i)          //     Add the current value and the input together
                   %26       //     Take modulo-26 of it to get the index in the alphabet
                      +65))) //     And add 65 to make it an uppercase letter

为什么不用不可打印的数字代替数字?这样,您可以忽略i-47
无知

@EmbodimentofIgnorance恐怕它不会保存任何字节。空格数分别为3、1、6和10。10被使用3次,每个字符为2个字节(\n)。所以,无论我用unprintables和3X \ni或数字-1 i-47,两者是相同的134字节数。不幸的是,我不能有一个0unprintable,否则我可以改用2,0,5,9,并i+1总共节省1个字节。
凯文·克鲁伊森

2

Wolfram语言(Mathematica),258个字节

(t[x_]:=Table[" ",x];w=RotateRight[Alphabet[],4-LetterNumber@#];j=Join;a[x_,y_]:=j[{w[[x]]},t@10,{w[[y]]}];b[m_,n_]:=j[t@1,w[[m;;m+1]],t@6,w[[n;;n+1]],t@1];""<>#&/@{j[t@3,w[[1;;6]]],b[25,7],a[24,9],a[23,10],a[22,11],Reverse@b[12,20],j[t@3,w[[19;;14;;-1]]]})&

在线尝试!


2

Haskell,127个字节

("cXYZABC aVWfDE UjF TjG SjH aRQfJI cPONMLK">>=).(?)
t?c|c>'Z'=' '<$['a'..c]|c<'!'="\n"|t<'B'=[c]|c>'Y'=t?'@'|1<2=pred t?succ c

在线尝试!

编码字符串中的每个字符都通过函数解码?为字符串:

t?c                             -- 't' is the starting char,
                                -- 'c' the char from the encoded string
   |c>'Z'=' '<$['a'..c]         -- if 'c' is a lowercase letter, return some spaces
                                -- 'a': one, 'b': two, etc
   |c<'!'="\n"                  -- if 'c' is a space, return a newline
   |t<'B'=[c]                   -- if 't' is the letter A, return 'c'
   |c>'Y'=t?'@'                 -- wrap around Z
   |1<2=pred t?succ c           -- else the result is the same as starting one letter
                                -- earlier (pred t) but looking at the successor of 'c'

2

科特林148个 146 145字节

删除了-2的多余括号
替换了-1的原始字符串

{l:Char->"2XYZABC 0VW5DE U9F T9G S9H 0RQ5JI 2PONMLK".map{c->if(c>'@')((c-'A'+(l-'A'))%26+65).toChar()
else if(c>' ')" ".repeat(c-'/')
else '\n'}}

在线尝试!



2

TSQL查询,238个字节

DECLARE @y char='G'

,@ char(91)=3;WITH C as(SELECT'5585877636333330301125255'z,8a,ascii(@y)x
UNION ALL
SELECT stuff(z,1,1,''),a+left(z,1)/3*13+left(z,1)%3-14,(x+14)%26+65FROM
C WHERE''<z)SELECT
@=stuff(stuff(@,a,1,char(x)),1+a/13*13,1,char(13))FROM
C PRINT @

此答案的测试链接中断了换行符并排除了空格。为了显示可读的结果,我将空格替换为句点,并将char(13)替换为char(13)+ char(10)。

在线尝试

取消高尔夫:

DECLARE @y char='G'

-- @ is the string being printed last. 
-- @ is populated with 3 to save a byte
-- the number 3 gets replaced later
-- (this could have been any 1 digit value), 
-- @ is automatically filled with spaces, because
-- it is declared as a char(x) and assigned a value
,@ char(91)=3;
-- recursive query
WITH C as
(
-- z string containing digits for the direction of next letter
-- z should not contain 4 because it will point to same position.
-- values in z 0,1,2,3,4,5,6,7,8 can logally convert to 
-- (-1,-1),(-1,0),(-1,1),(0,-1),(0,0),(0,1),(1,-1),(1,0),(1,1)
-- a is the starting position
  SELECT'5585877636333330301125255'z,8a,ascii(@y)x
  UNION ALL
-- stuff remove first character from the z string
-- a calculate next position of the next letter
-- x cycle the input letter
  SELECT stuff(z,1,1,''),a+left(z,1)/3*13+left(z,1)%3-14,(x+14)%26+65
-- repeat recursive until long string is empty
  FROM C
  WHERE''<z
)
SELECT
-- 1st stuff replace the character to created the start of a 
--   logical line in the string @ this is where 3 gets overwritten
-- 2nd stuff replaces a character(space if coded correct) 
--  with the letter at the calculated position.
  @=stuff(stuff(@,a,1,char(x)),1+a/13*13,1,char(13))
FROM C

PRINT @

@MickyT好的,谢谢您的反馈,如果我可以访问数据库,我将在今天晚些时候修复它
t-clausen.dk

@MickyT,现在应该修复
t-clausen.dk

1
现在看起来不错。
MickyT

1

PHP236个 229 226字节

<?=($a=ord(file_get_contents('php://stdin'))-65)?preg_replace_callback('~\w~',function($m)use($a){return chr((ord($m[0])-65+$a)%26+65);},'   XYZABC
 VW      DE
U          F
T          G
S          H
 RQ      JI
   PONMLK'):'';

在线尝试!

高尔夫前:

<?php
$adjust = ord(file_get_contents('php://stdin')) - 65;
echo preg_replace_callback('~\w~', function($match) use ($adjust) {
    $new = ord($match[0]) - 65;
    $new = ($new + $adjust) % 26;
    $new += 65;
    return chr($new);
}, '   XYZABC
 VW      DE
U          F
T          G
S          H
 RQ      JI
   PONMLK');

说明:

使用ord我们,将其转换为0到255之间的整数。A为65,Z为90。
使用此知识,我们获得输入并将其减少65,因此我们有了一个调整值。
然后,我们遍历所有字符,调用ord它们,将它们减少65,然后将其增加我们的调整值。使用取模,如果它们超过26,
我们将循环回零。然后再将其增加65,然后将它们转换回字母为chr

遗憾的是php:// stdin只能被查询一次,因此我们需要将输入传递到循环中的函数中,从而防止我们保存字节use($a)并在函数外部声明变量,这使我们无法使用<?=echo方法-我们必须将所有内容包裹在一个巨大的三元组中。


1

C(GCC)286字节

并非最短的高尔夫,但它能奏效

#define r(a)(a+c)%26+65
#define R(a)for(i=10;i;a[--i]<33?:(a[i]=r(a[i])));
i;f(c){char*S="          ",T[]="   XYZABC\n",E[]="VW      DE\n",F[]="RQ      JI\n",B[]="   PONMLK";R(T)R(E)R(F)R(B)printf("%s %s%c%s%c\n%c%s%c\n%c%s%c\n %s%s",T,E,r(85),S,r(70),r(84),S,r(71),r(83),S,r(72),F,B);}

在线尝试





0

Javascript(V8),316个字节

function a(b){n="abcdefghijklmnopqrstuvwxyz".split(b);n=b+n[1]+n[0],console.log(`   ${n[23]+n[24]+n[25]+n[0]+n[1]+n[2]}\n ${n[21]+n[22]}      ${n[3]+n[4]}\n${n[20]}          ${n[5]}\n${n[19]}          ${n[6]}\n${n[18]}          ${n[7]}\n ${n[17]+n[16]}      ${n[9]+n[8]}\n   ${n[15]+n[14]+n[13]+n[12]+n[11]+n[10]}`)}

在线尝试

第一次尝试打出代码。感谢任何提示/反馈。

缩小之前的原始代码:

function a(b){
    var c = ("abcdefghijklmnopqrstuvwxyz").split(b);
    c = b+c[1]+c[0]
    console.log(`   ${c[23]+c[24]+c[25]+c[0]+c[1]+c[2]}\n ${c[21]+c[22]}      ${c[3]+c[4]}\n${c[20]}          ${c[5]}\n${c[19]}          ${c[6]}\n${c[18]}          ${c[7]}\n ${c[17]+c[16]}      ${c[9]+c[8]}\n   ${c[15]+c[14]+c[13]+c[12]+c[11]+c[10]}`)
}

您好,欢迎来到PPCG。就目前而言,您的提交是一个片段,这是无效的I / O。请修正您的答案,使其成为完整程序或完整功能-就像您的非缩小版一样。
Jonathan Frech

@乔纳森·弗雷施谢​​谢!这样就够了吗?
蔡卓妍

1
是的,这现在是有效的提交。
Jonathan Frech


0

C(gcc)200 198 197字节

--3个字节,感谢ceilingcat。

x,z;f(c){char*y,t[27],i=0;for(c-=46;i<14;t[13+i++]=(c-i)%26+65)t[i]=(c+i)%26+65;for(i=-4;++i<4;printf("%*.*s%*.*s\n",3273>>x*3&7,x?:1,y,z,x?:1,y+2*!i+z))z="--*%"[x=abs(i)]-34,y=t+x+(x>2)+13*(i>0);}

在线尝试!


0

PHP,131字节

for(;$s='2YZABCD
 WX5EF
V9G
U9H
T9I
 SR5KJ
2QPONML'[$i++];)echo$s<A?$s<'0'?$s:str_pad('',$s+1,' '):chr(65+(ord($s)+ord($argn))%26);

在线尝试!

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.