Оценка признательности пользователей № 1: Деннис ♦


53

Мне пришла в голову спонтанная идея сделать серию испытаний для пользователей, которые помогали и продолжают помогать сообществу PPCG быть приятным местом для всех или, может быть, специально для меня. :П

Если вы преобразуете имя Денниса в массив 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 Coneheringaahing

@cairdcoinheringaahing Спасибо, что напомнили мне. Речь пойдет о Мего (обозначение ТНБ, следовательно, курсив), но я еще не дошел до его завершения.
HyperNeutrino

я должен сказать ему, или он просто нырнул в воду, чтобы искать рыбу?
Caird Coneheringaahing

@cairdcoinheringaahing Я уверен, что он уже знает; Я сказал, что сделаю с ним один, но я еще не решил, собираюсь ли я что-то делать с пингвинами или TNB.
HyperNeutrino

Я считаю, пингвины. Это то, что он знает (для меня)
caird coinheringaahing

Ответы:


15

05AB1E , 9 байтов

žM¹álSåÂQ

Попробуйте онлайн!

-2 спасибо Аднану .

Это точно атакует болевую точку Желе. Он использует lи A1-байтовые эквиваленты для Jelly's Œlи Øaсоответственно.


Вы уверены, что это работает? Запустите это
MCCCS

@ MCCCS Хм, вы можете быть правы.
Эрик Outgolfer

Вы можете заменить на áи DRна Â.
Аднан,

@Adnan Забыл á, не знал, что Âделает, спасибо!
Эрик Outgolfer

11
@alexis большинство из этих языков гольфа использует 256 различных символы и пользовательский кодовую , который отображает шестнадцатеричный 00для FFтем 256 символов, увидеть Jelly ответа
Стивен


13

32-разрядная функция машинного кода x86, 42 41 байт

В настоящее время самый короткий ответ на языке без игры в гольф, на 1В короче, чем у @ Streetter's q / kdb + .

С 0 для правдивых и ненулевых для ложных: 41 40 байт. (в общем случае сохраняет 1 байт для 32-разрядных, 2 байта для 64-разрядных).

Со строками неявной длины (в стиле C в стиле 0): 45 44 байта

Машинный код x86-64 (с 32-битными указателями, как x32 ABI): 44 43 байта .

x86-64 со строками неявной длины, по-прежнему 46 байтов (стратегия битовых карт shift / mask теперь безубыточна).

Это функция C подписи _Bool dennis_like(size_t ecx, const char *esi). Соглашение о вызовах немного нестандартно, близко к MS vectorcall / fastcall, но с другими регистрами arg: строка в ESI и длина в ECX. Это только забивает его arg-regs и EDX. AL содержит возвращаемое значение, а старшие байты содержат мусор (как это разрешено ABI SysV x86 и x32. IDK, что ABI MS говорят о высоком мусоре при возврате bool или узких целых чисел.)


Объяснение алгоритма :

Зацикливание входной строки, фильтрация и классификация в логический массив в стеке: для каждого байта проверьте, является ли он буквенным символом (если нет, переходите к следующему символу), и преобразуйте его в целое число от 0-25 (AZ) , Используйте это 0-25 целое число, чтобы проверить битовую карту vowel = 0 / consonant = 1. (Растровое изображение загружается в регистр как 32-битная непосредственная константа). Вставьте 0 или 0xFF в стек в соответствии с результатом растрового изображения (фактически в младшем байте 32-битного элемента, который может содержать мусор в верхних 3 байтах).

Первый цикл создает массив 0 или 0xFF (в элементах dword, заполненных мусором). Выполните обычную проверку палиндрома со вторым циклом, который останавливается, когда указатели пересекаются в середине (или когда они оба указывают на один и тот же элемент, если было нечетное количество буквенных символов). Восходящий указатель является указателем стека, и мы используем POP для загрузки + приращения. Вместо сравнения / setcc в этом цикле мы можем просто использовать XOR для определения того же / другого, поскольку существует только два возможных значения. Мы могли бы накапливать (с помощью ИЛИ), нашли ли мы какие-либо несоответствующие элементы, но ранняя ветвь на флагах, установленных XOR, по крайней мере, так же хороша.

Обратите внимание, что второй цикл использует byteразмер операнда, поэтому ему все равно, какой мусор первый цикл оставляет вне младшего байта каждого элемента массива.


Он использует недокументированную salcинструкцию для установки AL из CF таким же образом, как это sbb al,alбыло бы. Он поддерживается на любом процессоре Intel (кроме 64-битного режима), даже в Knight's Landing! Agner Fog перечисляет время для этого на всех процессорах AMD (включая Ryzen), поэтому, если производители x86 настаивают на том, чтобы связать этот байт пространства кода операции с 8086 года, мы могли бы также воспользоваться этим.

Интересные трюки:

  • трюк сравнения без знака для комбинированных функций isalpha () и toupper (), а также нулевое расширение байта для заполнения eax, настроенное для:
  • немедленное растровое изображение в регистре для bt, вдохновленное некоторыми хорошими выходными данными компилятора дляswitch .
  • Создание массива переменного размера в стеке с циклом push in. (Стандартно для asm, но не то, что вы можете сделать с C для строковой версии неявной длины). Он использует 4 байта стекового пространства для каждого входного символа, но экономит по крайней мере 1 байт против оптимальной игры в гольф stosb.
  • Вместо cmp / setne в логическом массиве XOR объединяет логические значения для непосредственного получения значения истинности. ( cmp/ salcне вариант, потому что salcработает только для CF, а 0xFF-0 не устанавливает CF. seteсоставляет 3 байта, но позволит избежать incвнешнего цикла, за чистую стоимость 2 байта (1 в 64-битном режиме )) против 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 раза не приводит к большим потерям кэша. (Это также может привести к тому, что ответы, в которых раньше не было строк, подобных Деннису, перед циклическим перебором по всем символам, имеют ранний выход.) Это salcпроисходит медленнее, чем setccна многих процессорах (например, 3 мопа против 1 на Skylake), но проверка битовой карты с bt/salcвсе еще быстрее, чем поиск строки или регулярное выражение. И нет никаких накладных расходов на запуск, поэтому это очень дешево для коротких строк.

Выполнение этого за один проход на лету означало бы повторение классификационного кода для направлений вверх и вниз. Это было бы быстрее, но с большим размером кода. (Конечно, если вы хотите быстро, вы можете сделать 16 или 32 символа одновременно с SSE2 или AVX2, все еще используя трюк сравнения, сдвигая диапазон к нижней части подписанного диапазона).


Тестовая программа (для ia32 или x32 Linux) для вызова этой функции с помощью аргумента cmdline и выхода из состояния = возвращаемое значение. strlenреализация от int80h.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. Это также потребовало бы дополнительного байта для decили notв конце (потому что только 32-битный имеет 1 байт inc / dec r32). Используя x32 ABI (32-битные указатели в длинном режиме), мы все еще можем избежать префиксов REX, даже если мы копируем и сравниваем указатели.

setc [rdi]Можно записывать напрямую в память, но резервирование байтов стека в ECX стоит больше кода, чем экономит. (И нам нужно перемещаться по выходному массиву. [rdi+rcx]Для режима адресации требуется один дополнительный байт, но на самом деле нам нужен счетчик, который не обновляется для отфильтрованных символов, поэтому он будет хуже, чем этот.)


Это источник YASM / NASM с %ifусловными обозначениями . Он может быть построен с -felf32(32-битным кодом) или -felfx32(64-битным кодом с x32 ABI) и с неявной или явной длиной . Я протестировал все 4 версии. Смотрите этот ответ для скрипта для создания статического двоичного файла из источника NASM / YASM.

Чтобы протестировать 64-битную версию на машине без поддержки ABI x32, вы можете изменить регистры указателя на 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, используйте shift / mask, чтобы выделить нужный бит из битовой карты.

%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

Так как это производит 0/1 в AL в конце (вместо 0 / 0xFF), мы можем сделать необходимое инвертирование возвращаемого значения в конце функции с помощью xor al, 1(2B) вместо dec eax(также 2B в x86-64) для по-прежнему производят правильное bool/_Bool возвращаемое значение.

Это использовалось для сохранения 1B для x86-64 со строками неявной длины, избегая необходимости обнулять старшие байты EAX. (Я использовал and eax, 0x7F ^ 0x20для преобразования в верхний регистр и обнуления оставшуюся часть eax с помощью 3-байтового кода and r32,imm8. Но теперь я использую 2-байтовую кодировку немедленного с AL, которую имеет большинство инструкций 8086, как я уже делал для subи cmp.)

Он проигрывает в bt/ salcв 32-битном режиме, и для строк с явной длиной требуется ECX для подсчета, поэтому это тоже не работает.

Но потом я понял, что был неправ: bt edx, eaxвсе еще работает с большим мусором в EAX. Это , по- видимому маскирует сдвиг рассчитывать так же , как shr r32, clделает ( если смотреть только на низких 5 битов ХЛ). Это отличается от того bt [mem], reg, к которому можно обращаться за пределами памяти, на которую ссылается режим / размер адресации, рассматривая ее как цепочку битов. (Сумасшедший CISC ...)

Руководство Intel по установке insn set не документирует маскировку, поэтому, возможно, это недокументированное поведение, которое Intel сохраняет на данный момент. (Подобные вещи не редкость. bsf dst, srcС src = 0 всегда оставляет dst неизмененным, даже если в этом случае задокументировано, что dst содержит неопределенное значение. AMD фактически документирует поведение src = 0.) Я тестировал на Skylake и Core2, и btверсия работает с ненулевым мусором в EAX за пределами AL.

Опрятный трюк здесь использует xchg eax,ecx(1 байт), чтобы получить счетчик в CL. К сожалению, BMI2 shrx eax, edx, eaxсоставляет 5 байтов, по сравнению только с 2 байтами для shr eax, cl. Для использования 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
^.?$

Попробуйте онлайн!

Сохранено 2 байта благодаря Нейлу.

Сохранено еще 2 байта благодаря Мартину.

Удаляет не-буквы, затем заменяет гласные на 1 и согласные на 2, чтобы получить согласованные значения. Затем несколько раз удаляет первый и последний символ, если они совпадают. Если это не так, слово будет симметричным, если останется один или ноль символов.


Работает ли \D 2ты, чтобы сэкономить пару байтов T`lL`2?
Нил

@Neil Да, похоже, хороший улов!
FryAmTheEggman

Отлично сработано. Я пытался сделать это :(
Кристофер

7

PHP, 82 байта

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

Попробуйте онлайн!


Вы можете предварять типажей (bool)и удалите $s=и ==$sпроверьте , чтобы сохранить 1 байт.
Кайзер

Если я не ошибаюсь, вы можете заменить (bool)просто 0||сказать false или ... вместо этого, сохранив 3 дополнительных байта.
Кайзер

Гектометр Не могли бы вы использовать \wдля символов слова вместо a-z?
Кайзер

@kaiser \wсодержит цифры подчеркивания и буквы. Это не будет работать и [^/p{L}]дольше, как [^a-z]плюс я. Я сравниваю обратную строку со строкой, поэтому $sона необходима для создания логического значения
Йорг Хюльсерманн

Это правда. Все же остальные должны работать. «Должен»… они делают.
Кайзер

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

Вы демонстрируете это с «Мартином Эндером» вместо «Денниса»? я должен снова посмотреть на название вызова.
Роман Греф

1
Предположительно Suever хотел демонстрацию, которая имела некоторое количество фильтрации на первом этапе.
Грег Мартин

Тогда он должен использовать «Алекс А.» вместо этого у него тоже есть период.
Эрик Outgolfer

2
Я запутался, в чем проблема. Я выбрал Мартина Эндера, потому что это было бы действительно так, если вы удалите пробелы и ложь в противном случае. Я также включил ссылку на все тестовые случаи
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даже если вам нужно переключиться на не-poitfree. 2) <$>idлишнее. f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,cэль ['A'..'Z']++['a'..'z']].
Ними

Вы можете оставить пробел между cи "для еще одного байта.
Ними

1
Я думаю, что c`elem`['A'..'Z']++['a'..'z']может быть сокращено до'@'<c,c<'{','`'<c||c<'['
Zgarb

5

Pyth, 18 15 байт

_I/L"aeiou"@Gr0

Попробуй это здесь.

-2 спасибо КарлКастору , а впоследствии -1.


16 байтов: _I/L"aeiou"@Grz0(с использованием оператора инвариантности I)
KarlKastor

@KarlKastor Я знал, что должен быть такой оператор ... спасибо. (Кстати, теперь я тоже могу удалить z, я приму цитаты ввода)
Эрик Outgolfer


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 байт

Сохранено 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], оставляя нас [65..90, 97..122]. Это те кодовые точки, которые мы хотим.

Теперь, когда мы создали список кодовых точек верхнего / нижнего алфавита, мы продолжаем нашу функцию фильтрации. Функция отображается на каждый символ входной строки, который, как я изначально сказал, вместо этого анализируется как ее код. Так что теперь у нас по существу есть [codepoint, [65..90, 97..122]]. Чтобы выяснить, является ли символ codepointбуквой, мы просто берем его индекс в нашем списке. Если его там нет, мы -1вместо этого получим индекс.

Прямо сейчас мы получаем значение Falsey только в том случае codepoint == 65, если , то есть первый индекс в нашем списке, так как только тогда индекс будет равен 0. Но единственное приращение решит эту проблему, и теперь, если оно codepointесть в нашем списке, мы получить его индекс + 1, который всегда является положительным числом, таким образом, всегда правдивым, а если его нет, мы получим -1 + 1 = 0, т.е.

Наконец, мы применяем функцию, которую я описал, к каждому символу ввода, и мы берем только те символы, для которых функция вернула истинный результат.

Затем мы должны определить, является ли каждый символ гласным или согласным. Поскольку гласных меньше, чем согласных, создание строки гласных, так что мы проверяем это условие, короче, чем создание строки согласных, поэтому мы проверяем, является ли каждый символ гласным. Но, чтобы проверить, является ли логический список палиндромным, нам нужны логические значения, которые мы не получим, просто взяв индекс + 1, поскольку это может привести к любому числу [1..10], если char является гласным. И, как большинство языков для игры в гольф, этот также не имеет boolфункции. Итак, мы просто используем not not x, так как notвсегда возвращает логическое значение. Но ждать; нам действительно нужно иметь конкретные логические значения? Поскольку notвсегда возвращает логическое значение, почему бы нам просто не удалить второеnotи на самом деле проверить, является ли каждый символ согласным? Да, именно это мы и сделаем!

После проверки, которая возвращает список логических значений, мы проверяем, является ли полученный нами логический список палиндромом, что и требует эта задача. Ну, каково определение палиндрома? Да, палиндром - это список или строка, равная его обратному. Итак, как мы проверяем? Просто, мы дублируем его, берем его обратное и сверяем с оригинальным списком. В итоге мы получаем то , что должен вернуть наш код.


1
Гигантское объяснение 42-байтовой программы. Теперь я предполагаю, что это в значительной степени говорит само за себя ...
Эрик Outgolfer

2

PHP , 87 байт

Regex бесплатная версия PHP. Добавлен "гласный", так как stripos может возвращать 0, что является ложным в PHP.

Ошибка исправлена ​​Йоргом.

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);но он
дает

@ 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 байта; переключение reverseна эквивалент K|:

2

CJam , 26 байт

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

Попробуйте онлайн!

-1 спасибо Esolanging Fruit .


Вы можете заменить 26,'af+на, '{,97>чтобы сохранить байт.
Esolanging Fruit

@EsolangingFruit такой старый ответ ...
Эрик Outgolfer

Байт, сохраненный полгода назад, ничем не отличается от байта, сохраненного сейчас. Это не похоже на инфляцию байтов или что-то в этом
роде

@EsolangingFruit Я имел в виду мой постоянно развивающийся опыт игры в гольф ... конечно, ты получил кредит как обычно, не волнуйся!
Эрик Outgolfer

2

Braingolf,  4  3 байта

&JP

-1 байт благодаря Эрику Аутгольферу

Оказывается, у меня было 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

Зачем вам нужен n?
Эрик Outgolfer

@EriktheOutgolfer, потому что я сертифицированный идиот
Skidsdev

Хм, ты забыл убрать это из объяснения.
Эрик Outgolfer

@EriktheOutgolfer Я был Гунна написать «Эрик», а затем вычеркнуть C, но это просто выглядит как «Эрик»
Skidsdev

Разве это не удастся для подобных Alex A.?
Shaggy

1

Python 2, 83 байта

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

Определяет функцию, которая дает TrueилиFalse


Вы можете сохранить 2 байта, используя "aeiouAEIOU".__contains__вместо 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в верхний регистр. Но я думаю, что это только спасает вас a-zи ан 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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.