用户赞赏挑战#1:Dennis♦


53

我有一个自发的想法,即向用户提出一系列挑战,这些挑战已经帮助并将继续帮助PPCG社区成为每个人(或者可能只是我个人)一个愉快的地方。:P

如果将Dennis的名称转换为1s和0s 的数组,其中每个辅音为1,每个元音为0,则该数组为[1, 0, 1, 1, 0, 1],这是对称的。因此,您面临的挑战是确定其他类似名称。

挑战

给定ASCII字符串,请删除所有不是字母的字符,并确定元音和辅音的配置是否对称。y不是元音

请注意,您的程序本身不必是这种类型的字符串。

测试用例

Dennis -> truthy
Martin -> truthy
Martin Ender -> truthy
Alex -> falsy
Alex A. -> truthy
Doorknob -> falsy
Mego -> falsy

参考实施

给定一个测试用例,此Python 3代码将提供正确的输出。这是我能做到的,但又不荒谬。

Python 3

s = input()
l = []
for c in s:
	if c in 'AEIOUaeiou':
		l.append(0)
	elif c in 'BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz':
		l.append(1)
print(l == list(reversed(l)), end = '')

在线尝试!


什么时候和谁是#2?
Caird coinheringaahing

@cairdcoinheringaahing感谢您提醒我。这将是关于Mego(TNB RO,因此是斜体),但我还没有最终确定它。
HyperNeutrino

我应该告诉他还是他只是潜入水中寻找鱼?
caird coinheringaahing

我很确定他已经知道了; @cairdcoinheringaahing。我说过我会为他做一个,但还没有决定是否要做与企鹅或TNB有关的事情。
HyperNeutrino

我估计是企鹅。这就是他知道(我)
凯尔德coinheringaahing

Answers:


15

05AB1E,9个字节

žM¹álSåÂQ

在线尝试!

-2感谢Adnan

这正好打击了果冻的痛点。它使用lA,1个字节的当量为果冻的ŒlØa分别。


您确定这可行吗?运行此
MCCCS

@MCCCS嗯,您可能是正确的。
暴民埃里克(Erik the Outgolfer)'17年

您可以替换通过áDR通过Â
阿德南

@Adnan忘记了á,不知道该怎么办Â,谢谢!
暴民埃里克(Erik the Outgolfer)'17年

11
@alexis大多数这些高尔夫语言使用256个不同的字符和一个映射十六进制的自定义代码页 00FF这些256个字符,看果冻答案
斯蒂芬·

18

果冻,11字节

ŒufØAe€ØCŒḂ

在线尝试!

备用版本:

ŒlfØae€ØCŒḂ

ŒufØAe€ØcŒḂ

ŒlfØae€ØcŒḂ

当然,赞赏丹尼斯的挑战必须以他的语言来回答。


15
Œuf是法文的Egg。只是说
-YSC

13

x86 32位机器代码功能,42 41字节

当前最短的非高尔夫语言答案,比1B短 @streetster的q / kdb +

对于真实,使用0表示,对于虚假使用非零值: 41 40字节。 (通常,对于32位,保存1字节,对于64位,保存2字节)。

使用隐式长度的字符串(C样式以0终止): 45 44字节

x86-64机器代码(带有32位指针,例如x32 ABI): 44 43个字节

x86-64具有隐式长度的字符串,仍然是46个字节(移位/掩码位图策略现在已达到收支平衡)。

这是带有C签名的函数 _Bool dennis_like(size_t ecx, const char *esi)。调用约定略微不标准,接近MS向量调用/快速调用,但具有不同的arg寄存器:ESI中的字符串和ECX中的长度。它只会破坏其arg-regs和EDX。AL保留返回值,高字节保留垃圾(如SysV x86和x32 ​​ABI所允许。IDK MS的ABI在返回布尔值或窄整数时所说的关于高垃圾的内容。)


算法说明

循环输入字符串,过滤并分类为堆栈上的布尔数组:对于每个字节,请检查其是否为字母字符(如果不是,则继续下一个字符),并将其转换为0-25(AZ)的整数。使用该0-25整数来检查元音= 0 /辅音= 1的位图。(位图作为32位立即数加载到寄存器中)。根据位图结果将0或0xFF压入堆栈(实际上是在32位元素的低字节中,前3个字节中可能有垃圾)。

第一个循环产生一个0或0xFF的数组(在用垃圾填充的dword元素中)。使用第二个循环进行通常的回文检查,该循环在指针在中间交叉时停止(或者,如果字母字符的奇数都指向相同的元素,则它们都指向同一元素)。向上移动的指针是堆栈指针,我们使用POP进行加载和递增。代替此循环中的compare / setcc,我们可以仅使用XOR来检测相同/不同,因为只有两个可能的值。我们可以累加(使用OR)是否找到任何不匹配的元素,但是在XOR设置的标志上的提前分支至少是一样好。

请注意,第二个循环使用byte操作数大小,因此它不在乎第一个循环在每个数组元素的低字节之外留下了什么垃圾。


它使用未记录的salc指令以相同的方式从CF设置AL sbb al,al。每个Intel CPU(64位模式除外)都支持它,甚至Knight's Landing! Agner Fog列出了它的时间安排了所有AMD CPU(包括Ryzen)上的,因此,如果x86供应商自8086起一直坚持占用该字节的操作码空间,我们也可能会利用它。

有趣的技巧:

  • 无符号比较技巧结合使用isalpha()和toupper()的,并将该字节零扩展以填充eax,设置为:
  • 的寄存器中的立即位图bt受一些不错的编译器输出的启发switch
  • 通过推入循环在堆栈上创建一个可变大小的数组。(asm的标准,但对于隐式长度字符串版本,您不能使用C来做)。它为每个输入字符使用4字节的堆栈空间,但与最佳打球相比至少节省了1字节stosb
  • 代替布尔数组上的cmp / setne,XOR布尔在一起直接获得真值。(cmp/ salc不是一个选项,因为salc仅适用于CF,而0xFF-0并未设置CF. sete为3字节,但避免inc了循环外,净成本为2字节(在64位模式下为1 ))与循环中的xor并使用inc。
; explicit-length version: input string in ESI, byte count in ECX
08048060 <dennis_like>:
 8048060:       55                      push   ebp
 8048061:       89 e5                   mov    ebp,esp  ; a stack frame lets us restore esp with LEAVE (1B)
 8048063:       ba ee be ef 03          mov    edx,0x3efbeee ; consonant bitmap

08048068 <dennis_like.filter_loop>:
 8048068:       ac                      lods   al,BYTE PTR ds:[esi]
 8048069:       24 5f                   and    al,0x5f    ; uppercase
 804806b:       2c 41                   sub    al,0x41    ; range-shift to 0..25
 804806d:       3c 19                   cmp    al,0x19    ; reject non-letters
 804806f:       77 05                   ja     8048076 <dennis_like.non_alpha>
 8048071:       0f a3 c2                bt     edx,eax    # AL = 0..25 = position in alphabet
 8048074:       d6                      SALC     ; set AL=0 or 0xFF from carry.  Undocumented insn, but widely supported
 8048075:       50                      push   eax
08048076 <dennis_like.non_alpha>:
 8048076:       e2 f0                   loop   8048068 <dennis_like.filter_loop>   # ecx = remaining string bytes
 ; end of first loop

 8048078:       89 ee                   mov    esi,ebp  ; ebp = one-past-the-top of the bool array
0804807a <dennis_like.palindrome_loop>:
 804807a:       58                      pop    eax      ; read from the bottom
 804807b:       83 ee 04                sub    esi,0x4
 804807e:       32 06                   xor    al,BYTE PTR [esi]
 8048080:       75 04                   jne    8048086 <dennis_like.non_palindrome>
 8048082:       39 e6                   cmp    esi,esp             ; until the pointers meet or cross in the middle
 8048084:       77 f4                   ja     804807a  <dennis_like.palindrome_loop>

08048086 <dennis_like.non_palindrome>:
 ; jump or fall-through to here with al holding an inverted boolean
 8048086:       40                      inc    eax
 8048087:       c9                      leave  
 8048088:       c3                      ret    
;; 0x89 - 0x60 = 41 bytes

这可能也是最快的答案之一,因为打高尔夫球的痛感并没有太严重,至少对于少于几千个字符的字符串而言,这种情况下4倍的内存使用不会造成很多缓存丢失。(它可能还会丢失在循环所有字符之前需要非丹尼斯类字符串的提早回答的答案。) salcsetcc许多CPU上的速度慢(例如3 uops与Skylake上的1),但是使用了位图检查bt/salc仍然比字符串搜索或正则表达式匹配快。而且没有启动开销,因此对于短字符串而言非常便宜。

快速进行一次操作将意味着重复上下方向的分类代码。那会更快,但是代码更大。(当然,如果需要快速,您可以使用SSE2或AVX2一次处理16个或32个字符,但仍然可以通过将范围移动到有符号范围的底部来使用比较技巧)。


测试程序(对于ia32或x32 Linux),以cmdline arg调用此函数,并以status =返回值退出。 strlenint80h.org实现。

; build with the same %define macros as the source below (so this uses 32-bit regs in 32-bit mode)
global _start
_start:
    ;%define PTRSIZE 4   ; true for x32 and 32-bit mode.

    mov  esi, [rsp+4 + 4*1]  ; esi = argv[1]
    ;mov  rsi, [rsp+8 + 8*1]  ; rsi = argv[1]   ; For regular x86-64 (not x32)

%if IMPLICIT_LENGTH == 0
        ; strlen(esi)
         mov     rdi, rsi
         mov     rcx, -1
        xor     eax, eax
        repne scasb    ; rcx = -strlen - 2
        not     rcx
        dec     rcx
%endif

    mov  eax, 0xFFFFAEBB   ; make sure the function works with garbage in EAX
    call dennis_like

    ;; use the 32-bit ABI _exit syscall, even in x32 code for simplicity
    mov ebx, eax
    mov eax, 1
    int 0x80           ; _exit( dennis_like(argv[1]) )

    ;; movzx edi, al   ; actually mov edi,eax is fine here, too
    ;; mov eax,231     ; 64-bit ABI exit_group( same thing )
    ;; syscall

可以使用此函数的64位版本,该版本sbb eax,eax只有2个字节,而不是3个字节setc al。它还需要一个额外的字节,decnot在结束(因为只有32位有1个字节INC / DEC R32)。使用x32 ABI(长模式下的32位指针),即使我们复制和比较指针,我们仍然可以避免使用REX前缀。

setc [rdi]可以直接写到内存,但是保留ECX字节的堆栈空间比节省更多的代码大小。(而且我们需要遍历输出数组。 [rdi+rcx]在寻址模式下要多花一个字节,但实际上我们需要一个不会针对过滤后的字符进行更新的计数器,因此它会变得更糟。)


这是带有%if条件的YASM / NASM源。可以使用-felf32(32位代码)或-felfx32(使用x32 ABI使用64位代码)以及隐式或显式length 构建。我已经测试了所有4个版本。请参阅此答案以获取用于从NASM / YASM源构建静态二进制文件的脚本。

要在不支持x32 ABI的计算机上测试64位版本,可以将指针regs更改为64位。(然后简单地从计数中减去REX.W = 1前缀的数量(0x48字节)。在这种情况下,需要4条指令使用REX前缀才能对64位寄存器进行操作)。或者,只需rsp在地址空间低4G中使用和输入指针来调用它。

%define IMPLICIT_LENGTH 0

; This source can be built as x32, or as plain old 32-bit mode
; x32 needs to push 64-bit regs, and using them in addressing modes avoids address-size prefixes
; 32-bit code needs to use the 32-bit names everywhere

;%if __BITS__ != 32   ; NASM-only
%ifidn __OUTPUT_FORMAT__, elfx32
%define CPUMODE 64
%define STACKWIDTH 8    ; push / pop 8 bytes
%else
%define CPUMODE 32
%define STACKWIDTH 4    ; push / pop 4 bytes
%define rax eax
%define rcx ecx
%define rsi esi
%define rdi edi
%define rbp ebp
%define rsp esp
%endif

    ; A regular x86-64 version needs 4 REX prefixes to handle 64-bit pointers
    ; I haven't cluttered the source with that, but I guess stuff like %define ebp rbp  would do the trick.


    ;; Calling convention similar to SysV x32, or to MS vectorcall, but with different arg regs
    ;; _Bool dennis_like_implicit(const char *esi)
    ;; _Bool dennis_like_explicit(size_t ecx, const char *esi)
global dennis_like
dennis_like:
    ; We want to restore esp later, so make a stack frame for LEAVE
    push  rbp
    mov   ebp, esp   ; enter 0,0 is 4 bytes.  Only saves bytes if we had a fixed-size allocation to do.

    ;         ZYXWVUTSRQPONMLKJIHGFEDCBA
    mov  edx, 11111011111011111011101110b   ; consonant/vowel bitmap for use with bt

;;; assume that len >= 1
%if IMPLICIT_LENGTH
    lodsb   ; pipelining the loop is 1B shorter than  jmp .non_alpha
.filter_loop:
%else
.filter_loop:
    lodsb
%endif

    and   al, 0x7F ^ 0x20  ; force ASCII to uppercase.
    sub   al, 'A'          ; range-shift to 'A' = 0
    cmp   al, 'Z'-'A'      ; if al was less than 'A', it will be a large unsigned number
    ja  .non_alpha
    ;; AL = position in alphabet (0-25)

    bt    edx, eax              ; 3B
%if CPUMODE == 32
    salc                        ; 1B   only sets AL = 0 or 0xFF.  Not available in 64-bit mode
%else
    sbb   eax, eax              ; 2B   eax = 0 or -1, according to CF.
%endif
    push  rax

.non_alpha:
%if IMPLICIT_LENGTH
    lodsb
    test   al,al
    jnz .filter_loop
%else
    loop .filter_loop
%endif
    ; al = potentially garbage if the last char was non-alpha
    ; esp = bottom of bool array

    mov   esi, ebp  ; ebp = one-past-the-top of the bool array
.palindrome_loop:
    pop   rax

    sub   esi, STACKWIDTH
    xor   al, [rsi]   ; al = (arr[up] != arr[--down]).  8-bit operand-size so flags are set from the non-garbage
    jnz .non_palindrome

    cmp   esi, esp
    ja .palindrome_loop

.non_palindrome:  ; we jump here with al=1 if we found a difference, or drop out of the loop with al=0 for no diff
    inc   eax     ;; AL transforms 0 -> 1  or  0xFF -> 0.
    leave
    ret           ; return value in AL.  high bytes of EAX are allowed to contain garbage.

我看着弄乱DF(控制lodsd/ 的方向标志,scasd依此类推),但似乎并没有取得成功。通常的ABI要求在函数进入和退出时清除DF。IMO认为,如果在进入时已清除但在退出时将其设置为欺骗。最好使用LODSD / SCASD来避免使用3个字节sub esi, 4,尤其是在没有高容量垃圾的情况下。


备用位图策略(用于x86-64隐式长度的字符串)

事实证明,这不会节省任何字节,因为bt r32,r32在位索引中仍然可以处理大量垃圾。只是没有记录方式shr

而不是bt / sbb让位进入CF或从CF中移出,请使用shift /掩码将所需的位与位图隔离。

%if IMPLICIT_LENGTH && CPUMODE == 64
    ; incompatible with LOOP for explicit-length, both need ECX.  In that case, bt/sbb is best
    xchg  eax, ecx
    mov   eax, 11111011111011111011101110b   ; not hoisted out of the loop
    shr   eax, cl
    and   al, 1
%else
    bt    edx, eax
    sbb   eax, eax
%endif
    push  rax

由于这将在AL末尾产生0/1(而不是0 / 0xFF),因此我们可以在函数末尾使用xor al, 1(2B)而不是dec eax(x86-64中也为2B)对返回值进行必要的反转仍然会产生适当的bool/_Bool返回值。

通过避免将EAX的高字节清零,这通常为x86-64使用隐式长度的字符串节省了1B。(我一直在用and eax, 0x7F ^ 0x203字节强制将其余的eax大写和置零and r32,imm8。但是现在我正在使用大多数8086指令具有的2字节即时AL编码,就像我已经在做的那样为subcmp。)

在32位模式下,它会丢失bt/ salc,并且显式长度的字符串需要ECX进行计数,因此在此也不起作用。

但是后来我意识到我错了:bt edx, eax在eax中仍然可以处理大量垃圾。它显然掩盖了移位数以同样的方式shr r32, cl(在CL的低5位仅看)。这与不同bt [mem], reg,后者可以在寻址模式/大小所引用的内存外部访问,将其视为位串。(疯狂的CISC ...)

英特尔的insn set ref手册没有记录屏蔽操作,因此,英特尔目前可能保留的是未记录的行为。(这种情况并不少见 bsf dst, src。src = 0的情况下,即使dst始终保持未定义的值,但dst始终保持不变。AMD实际上记录了src = 0的行为。)我在Skylake和Core2上进行了测试,该bt版本适用于AL以外的EAX中的非零垃圾。

一个巧妙的技巧是使用xchg eax,ecx(1个字节)将计数计入CL。不幸的是,BMI2 shrx eax, edx, eax是5个字节,而仅为2个字节shr eax, cl。using bextr需要一个2字节mov ah,1(用于提取的位数),因此它又是5 + 2字节,例如SHRX + AND。


添加%if条件后,源代码变得非常混乱。 这是x32隐式长度字符串的分解(使用位图的替代策略,因此仍然是46个字节)。

与显式长度版本的主要区别在于第一个循环。注意lods在它的前面和底部有一个,而不是在循环的顶部只有一个。

    ; 64-bit implicit-length version using the alternate bitmap strategy
    00400060 <dennis_like>:
      400060:       55                      push   rbp
      400061:       89 e5                   mov    ebp,esp
      400063:       ac                      lods   al,BYTE PTR ds:[rsi]

    00400064 <dennis_like.filter_loop>:
      400064:       24 5f                   and    al,0x5f
      400066:       2c 41                   sub    al,0x41
      400068:       3c 19                   cmp    al,0x19
      40006a:       77 0b                   ja     400077 <dennis_like.non_alpha>
      40006c:       91                      xchg   ecx,eax
      40006d:       b8 ee be ef 03          mov    eax,0x3efbeee  ; inside the loop since SHR destroys it
      400072:       d3 e8                   shr    eax,cl
      400074:       24 01                   and    al,0x1
      400076:       50                      push   rax
    00400077 <dennis_like.non_alpha>:
      400077:       ac                      lods   al,BYTE PTR ds:[rsi]
      400078:       84 c0                   test   al,al
      40007a:       75 e8                   jne    400064 <dennis_like.filter_loop>

      40007c:       89 ee                   mov    esi,ebp
    0040007e <dennis_like.palindrome_loop>:
      40007e:       58                      pop    rax
      40007f:       83 ee 08                sub    esi,0x8
      400082:       32 06                   xor    al,BYTE PTR [rsi]
      400084:       75 04                   jne    40008a <dennis_like.non_palindrome>
      400086:       39 e6                   cmp    esi,esp
      400088:       77 f4                   ja     40007e <dennis_like.palindrome_loop>

    0040008a <dennis_like.non_palindrome>:
      40008a:       ff c8                   dec    eax  ; invert the 0 / non-zero status of AL.  xor al,1 works too, and produces a proper bool.
      40008c:       c9                      leave  
      40008d:       c3                      ret    

   0x8e - 0x60 = 0x2e = 46 bytes

8

视网膜49 47 45字节

\P{L}

i`[aeiou]
1
\D
2
+`^(.)(.*)\1$
$2
^.?$

在线尝试!

感谢Neil,节省了2个字节。

感谢马丁,又节省了2个字节。

删除非字母,然后将元音替换为1,将辅音替换为2,以获得一致的值。然后重复删除第一个和最后一个字符(如果它们相同)。一旦不存在,则如果剩余一个或零个字符,则该单词是对称的。


难道\D 2工作为您节省了几个字节的过T`lL`2
尼尔

@Neil是的,不错!
FryAmTheEggman's

做得好。我正在尝试这样做:(
Christopher

7

PHP,82字节

<?=strrev($s=preg_replace(["#[^a-z]#i","#[aeiou]#i","#\pL#"],["",0,1],$argn))==$s;

在线尝试!


您可以在类型转换之前添加,(bool)然后删除$s===$s检查以保存1个字节。
kaiser

如果我没有记错的话,你可以更换(bool)0||假的,或...代替,节省了额外的3个字节。
kaiser

嗯 你不能使用\w字符代替a-z
kaiser

@kaiser \w包含数字下划线和字母。这将无法正常工作,并且[^/p{L}]会比[^a-z]plus i 更长。我比较反向串与串所以$s需要创建布尔
约尔格Hülsermann

那是真实的。其他人还是应该工作。“应该”……他们这样做。
kaiser

6

MATL,14个字节

t3Y2m)13Y2mtP=

MATL Online上尝试一下。

是一个稍作修改的版本,用于检查所有测试用例。

说明

        % Implicitly grab the input as a string
        %     STACK: {'Martin Ender'}
t       % Duplicate the input
        %     STACK: {'Martin Ender', 'Martin Ender'}
3Y2     % Push the string 'ABC...XYZabc...xyz'
        %     STACK: {'Martin Ender', 'Martin Ender', 'ABC...XYZabc...xyz'}
m       % Find which characters of the input are letters using this string
        %     STACK: {'Martin Ender', [1 1 1 1 1 1 0 1 1 1 1]}
)       % Use this boolean array to select only the letters
        %     STACK: {'MartinEnder'}
13Y2    % Push the string literal 'aeiouAEIOU' to the stack
        %     STACK: {'MartinEnder', 'aeiouAEIOU'}
m       % Check for membership of each letter of the input in this string.
        %     STACK: {[0 1 0 0 1 0 1 0 0 1 0]}
tP      % Create a reversed copy
        %     STACK: {[0 1 0 0 1 0 1 0 0 1 0], [0 1 0 0 1 0 1 0 0 1 0]}
=       % Perform an element-wise comparison yielding a truthy (all 1's) or 
        % falsey (any 0's) result
        %     STACK: {[1 1 1 1 1 1 1 1 1 1 1]}
        % Implicitly display the result

您用“马丁·恩德”代替“丹尼斯”证明了吗?我必须再次查看挑战标题。
罗曼·格拉夫(RomanGräf)

1
大概Suever想要一个演示,第一步需要进行一些过滤。
格雷格·马丁

然后,他应该使用“ Alex A”。相反,它也有一个时期。
暴民埃里克(Erik the Outgolfer)'17年

2
我很困惑这个问题是什么。我之所以选择Martin Ender,是因为如果删除空格,则实际上为true,否则为false。我还提供了所有测试用例的链接
Suever

6

Haskell,84 75 74 69字节

-10感谢@nimi
-5感谢@Zgarb

f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,'@'<c,c<'{','`'<c||c<'[']

列表推导将每个字母替换为布尔值,并删除所有其他字符。第一部分检查结果列表是否为回文。

在线尝试!


两个提示:1)即使您必须切换到非零无聊的情况,列表理解也通常比filter其后map要短。2)<$>id是多余的。f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,cELEM ['A'..'Z']++['a'..'z']]
nimi

您可以删除之间的空间c"一个多字节。
nimi

1
我认为c`elem`['A'..'Z']++['a'..'z']可以缩短为'@'<c,c<'{','`'<c||c<'['
Zgarb


4

Brachylog,13个字节

ḷ{∈Ṿg|∈Ḅg}ˢ.↔

在线尝试!

说明

ḷ                Lowercase the input
 {       }ˢ.     Select each char if:
  ∈Ṿg              it's a vowel, and replace it with ["aeiou"]            
     |             Or
      ∈Ḅg          it's a consonant, and replace it with ["bcdfghjklkmnpqrstvwxyz"]
           .↔    The resulting list is a palindrome

3

爱丽丝,28字节

/uia.QN."-e@
\1"lyuy.Ra$i1/o

在线尝试!

输出1为真实,没有虚假。

说明

该程序中的每个命令都以序数模式执行,但是模板略有扭曲,使我可以保存一个字节。如果换行符是可接受的真实值,则可以通过相同的方法再保存一个字节。

线性化后,程序如下:

1il.uN."aei ou"ayQy.R-$@1o1@

1                           % Append "1" to top of stack
                            % STACK: ["1"]
 i                          % Push input to stack
                            % STACK: ["1", "Dennis"]
  l                         % Convert to lowercase
                            % STACK: ["1", "dennis"]
   .                        % Duplicate
                            % STACK: ["1", "dennis", "dennis"]
    u                       % Convert to uppercase
                            % STACK: ["1", "dennis", "DENNIS"]
     N                      % Take multiset difference; this removes all non-alphabetic characters
                            % STACK: ["1", "dennis"]
      .                     % Duplicate
                            % STACK: ["1", "dennis", "dennis"]
       "aei ou"             % Push "aei ou"
                            % STACK: ["1", "dennis", "dennis", "aei ou"]
              a             % Push newline
                            % STACK: ["1", "dennis", "dennis", "aeiou", "\n"]
               y            % Transliterate: replace all vowels with newlines
                            % STACK: ["1", "dennis", "d\nnn\ns"]
                Q           % Reverse stack
                            % STACK: ["d\nnn\ns", "dennis", "1"]
                 y          % Transliterate: replace remaining characters with "1"
                            % STACK: ["1\n11\n1"]
                  .         % Duplicate
                            % STACK: ["1\n11\n1", "1\n11\n1"]
                   R        % Reverse top of stack
                            % STACK: ["1\n11\n1", "1\n11\n1"]
                    -       % Remove occurrences: for same-length strings, result is "" iff strings are equal.
                            % STACK: [""]
                     $      % Pop stack, and skip next command if ""
                      @     % Terminate (skipped if c/v pattern is palindromic)
                       1o   % Output "1"
                         1  % Push "1" (useless)
                          @ % Terminate


3

JavaScript(ES6),72 69字节

感谢Neil,节省了3个字节

返回一个布尔值。

s=>(a=s.match(/[a-z]/gi).map(c=>!/[aeiou]/i.exec(c)))+''==a.reverse()

测试用例


通过将2个空字符串替换为来节省几个字节2
毛茸茸的

1
您甚至需要+''结尾吗?那将节省3个字节。
尼尔

我更喜欢@Neil的主意!
毛茸茸的

2

Mathematica,113个字节

PalindromeQ@StringCases[StringReplace[#,{Characters["aeiouAEIOU"]->"1",CharacterRange["A","z"]->"0"}],{"0","1"}]&

您可以摆脱很多字节:PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
不是一棵树

2

GolfScript,42个字节

{123,65>.26>6<-?)},{"AEIOUaeiou"?)!}%.-1%=

在线尝试!

困难的部分是在一个字符串中生成大写和小写字母,我们将在过滤器函数中使用它来过滤输入中的字母。幸运的是,由于GolfScript中的字符串只是具有特殊属性的代码点数组,因此我们可以高效地生成代码点。这是我们生成它们的方式:

首先,我们生成范围[0..122],其中122是的代码点z。然后,从索引65开始的元素中获取元素。65是A。现在,我们有[65..122]。很好,除了我们那里有一些不需要的代码点([91..96])。因此,我们首先复制该范围。然后,我们从索引26开始获取元素,然后得到[91..122]。在那之后,我们得到的元素直到并包括索引5。现在我们有了[91..96]。最后,我们从[65..122]中删除这些元素,而将wil [65..90,97..122]留给我们。这些是我们想要的代码点。

现在我们已经创建了上/下字母代码点列表,我们继续进行过滤功能。该函数将映射到输入字符串上的每个字符,正如我最初所说的那样,它会被解析为其代码点。所以现在我们基本上有了[codepoint, [65..90, 97..122]]。要确定char codepoint是否为字母,我们只需将其索引添加到我们创建的列表中即可。如果不存在,我们将-1改为作为索引。

现在,仅当 codepoint == 65,即列表的第一个索引时,我们,因为只有那时索引才为0。但是单次递增将解决此问题,现在,如果codepoint在列表中,我们将得到它的索引+1,它总是一个正数,因此总是真实的;而如果不存在,我们将得到-1 + 1 = 0,即假。

最终,我们将我描述的函数应用于输入的每个字符,并且仅采用函数返回真实结果的字符。

接下来,我们必须确定每个字符是元音还是辅音。由于元音比辅音少,因此创建一串元音使我们检查该条件比创建一串辅音短,因此我们检查每个字符是否为元音。但是,要检查布尔值列表是否为回文,我们需要布尔值,我们不能仅通过获取索引+ 1来获得布尔值,因为如果char是元音,则可以得到任意数量的[1..10]。而且,与大多数高尔夫语言一样,该语言也没有bool功能。因此,我们总是使用not not x,因为not总是返回一个布尔值。可是等等; 我们真的需要特定的布尔值吗?从开始not总是返回布尔值,我们为什么不删除第二个not,并实际检查每个字符是否为辅音?是的,这就是我们要做的!

在检查后返回布尔值列表,然后检查是否得到的布尔值列表是回文,这是我们要求我们执行的操作。那么,回文的定义是什么?是的,回文是等于其反向的列表或字符串。那么,我们如何检查?很简单,我们将其复制,取反,并对照原始列表进行检查。最后,我们得到的结果是我们的代码应返回的内容。


1
42字节程序的详细解释。现在我猜想这几乎是不言而喻的……
Outgolfer的Erik

2

PHP,87字节

Regex免费的PHP版本。添加了“元音”,因为stripos可以返回0,这在PHP中为false。

约格修复的缺陷。

for(;a&$c=$argn[$p++];)!ctype_alpha($c)?:$s.=stripos(_aeiou,$c)?0:1;echo$s==strrev($s);

在线尝试!


相同的字节数。for(;a&$c=$argn[$p++];)ctype_alpha($c)?$s.=stripos(_aeiou,$c)?0:1:0;echo$s==strrev($s);但它得到的字符串正确的结果,其中包含零
约尔格Hülsermann

@JörgHülsermann谢谢。
ME

2

q / kdb +,42 38字节

解:

{x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower

例:

q){x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower"Dennis"
1b
q){x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower"Adam"
0b
q){x~|:[x]}{inter[x;.Q.a]in"aeiou"}lower"Alex A."
1b

说明:

lower        // converts argument on the right to lowercase
.Q.a         // lowercase alphabet "abc..xyz"
inter[x;y]   // intersection of x and y (thus only return a-z)
x in "aeiou" // returns boolean list whether x is a vowel; "dennis" = 010010b
|:           // k shorthand for 'reverse'

编辑:

  • -4字节; 换出reversek当量|:

2

CJam,26个字节

lel_'{,97>--"aeiou"fe=_W%=

在线尝试!

-1感谢Esolanging Fruit


您可以替换26,'af+使用'{,97>,以节省一个字节。
Esolanging Fruit '18

@EsolangingFruit这样的旧答案……
Outgolfer的Erik,18年

半年前保存的字节与现在保存的字节没有什么不同。这不像是字节膨胀或其他任何东西:P
硕果累累'18

@EsolangingFruit我指的是我在高尔夫球领域不断发展的经验...当然,您像往常一样获得荣誉,不用担心!
暴民埃里克(Erik the Outgolfer)'18年

2

Braingolf, 4个  3字节

&JP

-1个字节感谢外长者埃里克(Erik the Outgolfer)

事实证明P,即使在挑战之前我也一直。

J 但是,尽管在挑战之前就创建了它,但是在挑战之前并没有被推送到github,因此仍然是非竞争性的。

说明:

&JP  Implicit input, push ASCII value of each char in string to stack
&J   Replace each item in stack with 1 if vowel, otherwise 0
  P  Pop entire stack, push 1 if stack is palindromic, 0 otherwise
     Implicit output of last item on stack


@EriktheOutgolfer因为我是认证的白痴
Skidsdev

嗯,您忘了将其从说明中删除。
大公埃里克

@EriktheOutgolfer我是古纳,写了“ Erick”然后删除了c,但是看起来像是“ Eriek”
Skidsdev

这样的失败不会失败Alex A.吗?
粗野的

1

Python 2,83字节

def f(x):k=map(lambda y:y.lower()in"aeiou",filter(str.isalpha,x));return k==k[::-1]

定义一个提供TrueFalse


您可以使用"aeiouAEIOU".__contains__代替来保存2个字节lambda y:y.lower()in"aeiou"
搅拌器




1

重击,82字节

i=${1//[^a-zA-Z]};a=aeouiAEOUI;b=${i//[$a]/0};c=${b//[!0$a]/1};[ $c = `rev<<<$c` ]

在线尝试!

接收名称作为参数,删除非字母,将元音替换为0,将非元音替换为0,将非元音替换为1,然后将相同的颠倒进行比较。

如果可以进行双倍或三倍替代,可以打更多的高尔夫球

退出状态为0表示“真”,为1表示“否”。


在最新的bash版本中,i=${i^^*};转换i为大写。但是我认为这只会为您节省an a-z和an aeiou,这比它花费的10B小。
彼得·科德斯

1

Japt v2.0a0,19 11个字节

k\L mè\v ê¬

在线尝试


说明

        :Implicit input of string U.
 k\L    :Remove all non-letter characters from U.
 m      :Map over resulting string, replacing each character ...
 è\v    :with the count of the number of vowels in each single character substring.
 ê¬     :Is the above a palindrome?
        :Implicit output of boolean result.



0

公理,126字节

g(x)==~member?(x,alphabetic());v(s:String):Boolean==(w:=remove(g,s);a:=[member?(w.r,"aeiouAEIOU")for r in 1..#w];a=reverse(a))

测试

(8) -> [[i,v(i)] for i in ["Dennis", "Martin", "Martin Ender", "Alex", "Alex A.", "Doorknob", "Mego"]]
   (8)
   [["Dennis",true], ["Martin",true], ["Martin Ender",true], ["Alex",false],
    ["Alex A.",true], ["Doorknob",false], ["Mego",false]]
                                                      Type: List List Any

0

Pyke,12个字节

#B)l1~-L{D_q

在这里尝试!

#B)          -    filter(is_alpha, input)
   l1        -   ^.lower()
     ~-L{    -  ^ - "bcdfghjklmnpqrstvwxyz"
         D_q - ^ == reversed(^)

0

PowerShell,87字节

$s=("$args"-replace '\P{L}'-replace'[aeiou]',0-replace'\D',1);$s-eq(-join($s[-1..-99]))

获取元音为0且辅音为1的字符串的副本,并删除所有特殊字符,然后将该字符串与反向版本进行比较,再将其与返回到字符串的字符串进行比较

输出:

PS C:\Users\Connor> "Dennis","Martin","Martin Ender","Alex","Alex A.","Doorknob","Mego" | % {
    $s=("$_"-replace '\P{L}'-replace'[aeiou]',0-replace'\D',1);$s-eq(-join($s[-1..-99]))
}
True
True
True
False
True
False
False

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.