Завдання оцінці користувача №1: Dennis ♦


53

У мене виникла спонтанна ідея зробити низку викликів користувачів, які допомогли та надалі допомагають спільноті PPCG бути приємним місцем для всіх, а може бути, саме для мене. : P

Якщо ви перетворите ім'я Денніса в масив 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 дасть правильний вихід із тестового випадку. Це настільки ж невольф, як я міг би зробити це, не будучи смішним.

Пітон 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 Я впевнений, що він уже знає; Я сказав, що я зроблю його про нього, але ще не вирішив, чи збираюся я щось робити з пінгвінами чи ТНБ.
HyperNeutrino

Я вважаю пінгвінів. Це те, що він знає (для мене)
caird coinheringaahing

Відповіді:


15

05AB1E , 9 байт

žM¹álSåÂQ

Спробуйте в Інтернеті!

-2 завдяки Аднану .

Це точно нападає на біль у Джелі. Він використовує lі A, 1-байтові еквіваленти для Jelly Œlі Øaвідповідно.


Ви впевнені, що це працює? Запустити це
MCCCS

@MCCCS Хм, ви можете мати рацію.
Ерік Аутгольфер

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

@Adnan Забув á, не знав, що Âробить, дякую!
Ерік Аутгольфер

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


13

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

Наразі найкоротша відповідь на мові, що не використовується для гольфу, на 1B коротша за q / kdb + @ streetter .

З 0 для правдивої і ненульової для помилки: 41 40 байт. (загалом, економить 1 байт для 32-бітових, 2 байти для 64-розрядних).

З рядками неявної довжини (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 vectorcall / fastcall, але з різними аргументами аргументів: рядок у ESI та довжина в ECX. Він лише клобує свої аргументи та EDX. AL утримує повернене значення з високими байтами, що містять сміття (як це дозволяють ABI SysV x86 та x32.


Пояснення алгоритму :

Проведіть петлю над вхідним рядком, фільтруючи та класифікуючи булевий масив у стеку: для кожного байта перевірте, чи є він за алфавітом (якщо ні, перейдіть до наступного символу) та перетворіть його на ціле число від 0-25 (AZ) . Використовуйте це 0-25 ціле число, щоб перевірити растрові зображення голосних = 0 / приголосний = 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 .
  • Створення масиву змінного розміру на стеку із натисканням на цикл. (Стандартний для asm, але не те, що ви можете зробити з C для версії рядка неявної довжини). Він використовує 4 байти місця для стеку для кожного вхідного символу, але економить принаймні 1 байт проти оптимального гольфу навколо stosb.
  • Замість cmp / setne в бульовому масиві, XOR вводить булі разом, щоб безпосередньо отримати значення істини. ( cmp/ salcне є варіантом, тому що salcпрацює лише для CF, а 0xFF-0 не встановлює CF. sete3 байти, але це дозволить уникнути incзовнішньої петлі, чиста вартість 2 байти (1 у 64-бітному режимі) )) проти xor у циклі та фіксація його з укл.
; 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

Це, мабуть, також одна з найшвидших відповідей, оскільки жоден гольф насправді не шкодить занадто сильно, принаймні, для рядків розміром у декілька тисяч символів, де використання 4x пам’яті не спричиняє багато помилок кешу. (Можливо, це також втратить відповіді, які вимагають раннього відтворення рядків, не схожих на Денніса, перед тим, як переглядати всі символи.) salcПовільніше, ніж setccдля багатьох процесорів (наприклад, 3 Uops проти 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-бітну версію на машині без підтримки x32 ABI, ви можете змінити регістри вказівників на 64-бітні. (Тоді просто відніміть з числа кількість префіксів REX.W = 1 (0x48 байт). У цьому випадку для роботи на 64-бітних регістрах для 4 інструкцій потрібні префікси REX. Або просто зателефонуйте за 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щоб потрапляти в / з МВ, використовуйте 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

Оскільки в кінці цього виходить 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-AL, яке має більшість інструкцій 8086, як я вже робив для subі cmp.)

Він втрачає bt/ перебуває salcв 32-бітному режимі, і рядки явної довжини потребують ECX для підрахунку, так що це також не працює.

Але потім я зрозумів, що помилявся: bt edx, eaxдосі працює з високим сміттям в еаксі. Це, мабуть, маскує підрахунок зсуву так само, як shr r32, clце робить (дивлячись лише на низькі 5 біт кл). Це відрізняється від того bt [mem], reg, до якого можна отримати доступ поза пам'яттю, на яку посилається режим / розмір адресації, трактуючи це як бітовий рядок. (Божевільний CISC ...)

Інструкція Intel щодо встановлених посилань не містить документації щодо маскування, тому, можливо, Intel досі зберігає свою документацію. (Такі речі не є рідкістю. bsf dst, srcSrc = 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||сказати помилку, або… замість цього, зберегти 3 додаткові байти.
кайзер

Гм. Ви не можете використовувати \wдля символів слова замість a-z?
кайзер

@kaiser \wмістить підкреслення цифр та букви. Це не буде працювати і [^/p{L}]довше, ніж [^a-z]плюс я. Я порівнюю зворотний рядок із рядком, $sякий необхідний для створення булевого поля
Jörg Hülsermann,

Це правда. Ще інші повинні працювати. "Повинен" ... вони роблять.
кайзер

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
Імовірно, Сьювер хотів демонстрації, яка мала деяку кількість фільтрації на першому кроці.
Грег Мартін

Тоді він повинен використовувати "Алекс А." натомість у нього теж період.
Ерік Аутгольфер

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навіть якщо вам доведеться перейти на не-путфрі. 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

Піт, 18 15 байт

_I/L"aeiou"@Gr0

Спробуйте тут.

-2 завдяки КарлКастору , а згодом -1.


16 байт: _I/L"aeiou"@Grz0(за допомогою оператора інваріантності I)
КарлКастор

@KarlKastor Я знав, що повинен бути такий оператор, як ... дякую. (До речі, зараз я теж можу видалити z, я вважаю, що це цитується)
Ерік Попечитель


3

Аліса , 28 байт

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

Спробуйте в Інтернеті!

Вихідні дані не 1такі фальшиві, як і хибні.

Пояснення

Кожна команда в цій програмі виконується в порядковому режимі, але з невеликим поворотом у шаблоні, що дозволяє мені зберегти байт. Якщо новий рядок є прийнятним значенням truthy, я можу зберегти ще один байт тим же методом.

Лінійна програма, така:

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 байти.
Ніл

Мені більше подобається ідея @ Ніла!
Кудлатий

2

Математика, 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є буквою char , ми просто беремо її індекс у список, який ми склали. Якщо його немає, ми отримаємо -1замість цього індекс.

Зараз ми отримуємо значення фальси лише в тому випадку codepoint == 65, якщо , наприклад, перший індекс нашого списку, оскільки тільки тоді індекс буде дорівнює 0. Але один приріст виправить цю проблему, і тепер, якщо codepointє в нашому списку, ми отримаємо його індекс + 1, який завжди є додатним числом, таким чином, завжди є правдою, тоді як якщо його немає, ми отримаємо -1 + 1 = 0, тобто фальси.

Ми нарешті застосуємо описану мною функцію до кожної таблиці вводу, і ми беремо лише символи, для яких функція повернула тривалий результат.

Далі ми маємо визначити, чи кожен знак є голосним або приголосним. Оскільки голосних менше, ніж приголосних, то створення рядка голосних так, що ми перевіряємо, що ця умова є коротшою, ніж створення рядка приголосних, тому ми перевіряємо, чи є кожен знак голосним. Але, щоб перевірити, чи булевий список паліндромний, нам потрібні булеві, які ми не отримуємо лише шляхом взяття індексу + 1, оскільки це може призвести до будь-якої кількості [1..10], якщо знаком є ​​голосна. І, як і більшість мов для гри в гольф, цей також не має boolфункції. Отже, ми просто використовуємо not not x, оскільки notзавжди повертається булевим. Але чекай; нам справді потрібно мати конкретні булеви? Оскільки notзавжди повертається булевий, чому б нам просто не видалити другийnot, і насправді перевірте, чи кожен знак є приголосним? Так, саме так ми і зробимо!

Після чеку, який повертає список булевих, ми перевіряємо, чи є цей список булів, який ми отримали, паліндром, і саме це завдання вимагає від нас. Що ж таке визначення паліндром? Так, паліндром - це список або рядок, який дорівнює його зворотному напрямку. Отже, як ми перевіряємо? Просто, ми копіюємо його, приймаємо його зворотний бік і перевіряємо, чи не є оригінальний список. Результат, який ми отримуємо, це, нарешті , те, що повинен повернути наш код.


1
Гігантське пояснення 42-байтної програми. Тепер я здогадуюсь, що це досить само собою зрозуміло ...
Ерік Вигнавець

2

PHP , 87 байт

Безкоштовна версія PHP для Regex. Додано "голосну", оскільки 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 така стара відповідь ...
Erik the Outgolfer

Байт, збережений півроку тому, не відрізняється від байта, збереженого зараз. Це не так, як є інфляція на байтах чи що-небудь: P
Esolanging Fruit

@EsolangingFruit Я мав на увазі свій постійно розвиваючий досвід з гольфу ... звичайно, ти отримав кредит як завжди, не хвилюйся!
Ерік Аутгольфер

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?
Ерік Аутгольфер

@EriktheOutgolfer, тому що я сертифікований дебіл
Скідсдев

Хм, ви забули його видалити з пояснення.
Ерік Аутгольфер

@EriktheOutgolfer Мені було писати "Ерік", потім викреслити с, але це виглядає як "Ерік"
Скідсдев

Хіба це не вдасться подобатися 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.