Wyzwanie dotyczące uznania użytkownika nr 1: Dennis ♦


53

Spontanicznie wpadłem na pomysł stworzenia szeregu wyzwań dla użytkowników, którzy pomogli i nadal pomagają społeczności PPCG być przyjemnym miejscem dla wszystkich, a może tylko dla mnie. : P

Jeśli przekonwertujesz nazwę Dennisa na tablicę 1s i 0s, w której znajduje się każda spółgłoska 1i każda samogłoska 0, tablica [1, 0, 1, 1, 0, 1]jest symetryczna. Zatem Twoim wyzwaniem jest określenie, jakie są inne nazwy.

Wyzwanie

Biorąc pod uwagę ciąg ASCII, usuń wszystkie znaki, które nie są literami, i określ, czy konfiguracja samogłosek i spółgłosek jest symetryczna. ynie jest samogłoską.

Pamiętaj, że twój program nie musi być tego typu ciągiem.

Przypadki testowe

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

Wdrożenie referencyjne

Ten kod w Pythonie 3 da poprawne dane wyjściowe w przypadku testowym. Jest tak niezgrabny, jak tylko mogłem, bez śmieszności.

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 = '')

Wypróbuj online!


Kiedy i kto jest nr 2?
caird coinheringaahing

@cairdcoinheringaahing Dzięki za przypomnienie. Będzie to dotyczyło Mego (TNB RO, stąd kursywa), ale jeszcze nie udało mi się go sfinalizować.
HyperNeutrino,

powinienem mu powiedzieć, czy po prostu zanurkowałby w wodzie w poszukiwaniu ryb?
caird coinheringaahing

@cairdcoinheringaahing Jestem pewien, że już wie; Powiedziałem, że zrobię coś dla niego, ale nie zdecydowałem, czy zrobię coś związanego z pingwinami lub TNB.
HyperNeutrino,

Myślę, że pingwiny. Z tego jest znany (dla mnie)
Cairn coinheringaahing

Odpowiedzi:


15

05AB1E , 9 bajtów

žM¹álSåÂQ

Wypróbuj online!

-2 dzięki Adnan .

To atakuje dokładnie punkt bólu Jelly. Wykorzystuje li Arównoważniki 1-bajtowy dla Jelly Œli Øaodpowiednio.


Czy jesteś pewien, że to działa? Uruchom to
MCCCS

@MCCCS Hmm, możesz mieć rację.
Erik the Outgolfer

Możesz zastąpić przez ái DRprzez Â.
Adnan

@Adnan Zapomniałem á, nie wiedziałem, co Ârobi, dzięki!
Erik the Outgolfer

11
@alexis większość tych językach golfa użyć 256 różnych znaków i niestandardową stronę kodową, która mapuje hex 00do FFtych 256 znaków, patrz odpowiedź Jelly
Stephen


13

x86 32-bitowa funkcja kodu maszynowego, 42 41 bajtów

Obecnie najkrótsza odpowiedź w języku innym niż golf, 1B krótsza niż q / kdb + streetstera .

Zerem dla prawdy i niezerowym dla fałszu: 41 40 bajtów. (generalnie zapisuje 1 bajt dla wersji 32-bitowej, 2 bajty dla wersji 64-bitowej).

Z ciągami o niejawnej długości (w stylu C zakończonym 0): 45 44 bajtów

kod maszynowy x86-64 (z 32-bitowymi wskaźnikami, takimi jak x32 ABI): 44 43 bajty .

x86-64 z ciągami o niejawnej długości, wciąż 46 bajtów (strategia bitmapy shift / mask jest teraz na progu rentowności).

Jest to funkcja z C podpisu _Bool dennis_like(size_t ecx, const char *esi). Konwencja wywoływania jest nieco niestandardowa, zbliżona do MS wektorcall / fastcall, ale z różnymi rejestrami arg: ciąg znaków w ESI i długość w ECX. Blokuje tylko arg-regy i EDX. AL przechowuje wartość zwracaną, przy czym wysokie bajty przechowują śmieci (zgodnie z ABI SysV x86 i x32. IDK to, co ABI MS mówią o wysokich śmieciach podczas zwracania wartości bool lub wąskich liczb całkowitych.)


Objaśnienie algorytmu :

Pętla nad ciągiem wejściowym, filtrując i klasyfikując do tablicy boolowskiej na stosie: Dla każdego bajtu sprawdź, czy jest to znak alfabetyczny (jeśli nie, przejdź do następnego znaku) i przekształć go na liczbę całkowitą od 0-25 (AZ) . Użyj tej liczby całkowitej 0-25, aby sprawdzić bitmapę samogłoski = 0 / spółgłoska = 1. (Mapa bitowa jest ładowana do rejestru jako 32-bitowa stała natychmiastowa). Wciśnij 0 lub 0xFF na stos zgodnie z wynikiem bitmapy (w rzeczywistości w niskim bajcie elementu 32-bitowego, który może zawierać śmieci w pierwszych 3 bajtach).

Pierwsza pętla tworzy tablicę 0 lub 0xFF (w elementach dword wypełnionych śmieciami). Wykonaj zwykłe sprawdzanie palindromu za pomocą drugiej pętli, która zatrzymuje się, gdy wskaźniki przecinają się na środku (lub gdy oba wskazują na ten sam element, jeśli występuje nieparzysta liczba znaków alfabetycznych). Wskaźnik w górę jest wskaźnikiem stosu i używamy POP do ładowania + przyrostu. Zamiast porównywać / ustawiać w tej pętli, możemy po prostu użyć XOR do wykrycia tego samego / innego, ponieważ istnieją tylko dwie możliwe wartości. Możemy kumulować (za pomocą OR), czy znaleźliśmy jakieś niepasujące elementy, ale wczesna gałąź na flagach ustawionych przez XOR jest co najmniej tak dobra.

Zauważ, że druga pętla używa bytewielkości operandu, więc nie ma znaczenia, jakie śmieci pozostawia pierwsza pętla poza niskim bajtem każdego elementu tablicy.


Używa nieudokumentowanej salcinstrukcji, aby ustawić AL z CF w taki sam sposób, jak sbb al,alby to zrobił. Jest obsługiwany na każdym procesorze Intel (z wyjątkiem trybu 64-bitowego), nawet w Knight's Landing! Agner Fog podaje również czasy dla wszystkich procesorów AMD (w tym Ryzen), więc jeśli dostawcy x86 nalegają na ograniczenie tego bajtu przestrzeni opcode od 8086, równie dobrze moglibyśmy z niego skorzystać.

Ciekawe sztuczki:

  • trick bez porównania porównuje kombinację isalpha () i toupper (), a zero-wydłuża bajt, aby wypełnić eax, ustawiając dla:
  • natychmiastowa mapa bitowa w rejestrze dla bt, zainspirowana jakimś ładnym wyjściem kompilatora dlaswitch .
  • Tworzenie tablicy o zmiennej wielkości na stosie za pomocą pętli push. (Standard dla asm, ale nie jest to coś, co można zrobić z C dla wersji ciągu o niejawnej długości). Wykorzystuje 4 bajty miejsca na stosie na każdy znak wejściowy, ale oszczędza co najmniej 1 bajt w porównaniu do optymalnej gry w golfa stosb.
  • Zamiast cmp / setne na tablicy boolowskiej, boolany XOR razem uzyskują bezpośrednio wartość prawdy. ( cmp/ salcnie jest opcją, ponieważ salcdziała tylko dla CF, a 0xFF-0 nie ustawia CF. setema 3 bajty, ale uniknie inczewnętrznej pętli, koszt netto 2 bajtów (1 w trybie 64-bitowym )) vs. xor w pętli i ustalanie jej za pomocą 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

Jest to prawdopodobnie jedna z najszybszych odpowiedzi, ponieważ żadna gra w golfa nie boli tak bardzo, przynajmniej dla łańcuchów poniżej kilku tysięcy znaków, w których użycie pamięci 4x nie powoduje wielu braków pamięci podręcznej. (Może również stracić odpowiedzi, które wymagają wcześniejszego wypuszczenia ciągów niepochodzących od Dennisa przed zapętleniem wszystkich znaków.) salcJest wolniejsze niż setccna wielu procesorach (np. 3 ulepszenia vs. 1 na Skylake), ale sprawdzenie bitmapy z bt/salcjest nadal szybszy niż wyszukiwanie ciągów lub dopasowanie do wyrażenia regularnego. I nie ma narzutu związanego z uruchamianiem, więc jest wyjątkowo tani w przypadku krótkich ciągów.

Wykonanie tego w jednym przejściu w locie oznaczałoby powtórzenie kodu klasyfikacji dla kierunków w górę i w dół. Byłoby to szybsze, ale większy rozmiar kodu. (Oczywiście, jeśli chcesz szybko, możesz robić 16 lub 32 znaki jednocześnie za pomocą SSE2 lub AVX2, wciąż używając sztuczki porównywania, przesuwając zakres na dół podpisanego zakresu).


Program testowy (dla systemu Linux ia32 lub x32), aby wywołać tę funkcję za pomocą argumentu cmdline i wyjść ze statusu = zwracana wartość. strlenwdrożenie z 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

Można użyć 64-bitowej wersji tej funkcji sbb eax,eax, dla której są tylko 2 bajty zamiast 3 setc al. Potrzebowałby także dodatkowego bajtu na końcu declub notna końcu (ponieważ tylko 32-bit ma 1 bajt inc / dec r32). Używając x32 ABI (32-bitowe wskaźniki w trybie długim), nadal możemy uniknąć prefiksów REX, nawet jeśli kopiujemy i porównujemy wskaźniki.

setc [rdi]może zapisywać bezpośrednio do pamięci, ale rezerwowanie bajtów ECX miejsca na stosie kosztuje więcej kodu niż to oszczędza. (I musimy przechodzić przez tablicę wyjściową. [rdi+rcx]Zajmuje jeden dodatkowy bajt dla trybu adresowania, ale tak naprawdę potrzebujemy licznika, który nie aktualizuje filtrowanych znaków, więc będzie gorzej.)


To jest źródło YASM / NASM z parametrami %ifwarunkowymi. Może być zbudowany z -felf32(kod 32-bitowy) lub -felfx32( kod 64-bit z ABI x32) oraz z niejawną lub jawną długością . Przetestowałem wszystkie 4 wersje. Zobacz tę odpowiedź dotyczącą skryptu do tworzenia statycznego pliku binarnego ze źródła NASM / YASM.

Aby przetestować wersję 64-bitową na komputerze bez obsługi ABI x32, możesz zmienić rejestr wskaźnika na 64-bit. (Następnie wystarczy odjąć liczbę prefiksów REX.W = 1 (0x48 bajtów) od liczby. W takim przypadku 4 instrukcje wymagają prefiksów REX do działania na 64-bitowych rejestrach). Lub po prostu nazwij to wskaźnikiem rspi wskaźnikiem wejściowym w niskim 4G przestrzeni adresowej.

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

Patrzyłem na bałagan z DF (flagą kierunkową, która kontroluje lodsd/ scasdi tak dalej), ale nie wydawało się to zwycięstwem. Zwykłe ABI wymagają wyczyszczenia DF przy wejściu i wyjściu funkcji. Zakładając, że wyczyszczone przy wjeździe, ale pozostawienie go ustawionego przy wyjściu byłoby oszustwem, IMO. Byłoby miło użyć LODSD / SCASD, aby uniknąć 3-bajtów sub esi, 4, szczególnie w przypadku braku śmieci.


Alternatywna strategia bitmapowa (dla ciągów o niejawnej długości x86-64)

Okazuje się, że nie zapisuje to żadnych bajtów, ponieważ bt r32,r32nadal działa z dużymi śmieciami w indeksie bitów. Po prostu nie jest to udokumentowane shr.

Zamiast bt / sbbwprowadzić bit do / z CF, użyj shift / mask, aby odizolować bit, który chcemy od bitmapy.

%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

Ponieważ daje to 0/1 w AL na końcu (zamiast 0 / 0xFF), możemy wykonać niezbędną inwersję wartości zwracanej na końcu funkcji za pomocą xor al, 1(2B) zamiast dec eax(również 2B w x86-64), aby nadal generuje poprawną bool/_Bool zwracaną wartość.

W ten sposób zapisywano 1B dla x86-64 z ciągami o niejawnej długości, unikając konieczności zerowania wysokich bajtów EAX. (Używałem and eax, 0x7F ^ 0x20do wymuszania wielkich liter i zerowania reszty eax za pomocą 3-bajtowego and r32,imm8. Ale teraz używam 2-bajtowego kodowania natychmiastowego z AL, które ma większość instrukcji 8086, tak jak już to robiłem dla subi cmp.)

Traci do bt/ salcw trybie 32-bitowym, a ciągi o jawnej długości potrzebują ECX do zliczania, więc to też tam nie działa.

Ale potem zdałem sobie sprawę, że się myliłem: bt edx, eaxnadal działa z wysokimi śmieciami w eax. To widocznie maski Shift liczyć tak samo shr r32, clma (patrząc tylko na niskich 5 bitów CL). Różni się to od tego bt [mem], reg, który może uzyskiwać dostęp poza pamięcią, do której odnosi się tryb / rozmiar adresowania, traktując to jako ciąg bitów. (Crazy CISC ...)

Instrukcja odnawiania wewnętrznego zestawu Intela nie dokumentuje maskowania, więc może to nieudokumentowane zachowanie, które Intel na razie zachowuje. (Takie rzeczy nie są rzadkie. bsf dst, srcPrzy src = 0 zawsze pozostawia dst niezmodyfikowane, nawet jeśli udokumentowano, że dst ma w tym przypadku niezdefiniowaną wartość. AMD faktycznie dokumentuje zachowanie src = 0). Testowałem na Skylake i Core2, a btwersja działa z niezerowymi śmieciami w EAX poza AL.

Dobrą sztuczką jest użycie xchg eax,ecx(1 bajtu), aby uzyskać licznik w CL. Niestety BMI2 shrx eax, edx, eaxma 5 bajtów, a tylko 2 bajty shr eax, cl. Korzystanie bextrwymaga 2 bajtów mov ah,1(do liczby bitów do wyodrębnienia), więc znów jest to 5 + 2 bajtów, takich jak SHRX + AND.


Kod źródłowy stał się dość niechlujny po dodaniu %ifwarunkowych. Oto demontaż ciągów o niejawnej długości x32 (przy użyciu alternatywnej strategii dla mapy bitowej, więc nadal jest to 46 bajtów).

Główną różnicą w stosunku do wersji o jawnej długości jest pierwsza pętla. Zauważ, że jest lodsprzed nim i na dole, zamiast tylko jednego na górze pętli.

    ; 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

Siatkówka ,49 47 45 bajtów

\P{L}

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

Wypróbuj online!

Zaoszczędzono 2 bajty dzięki Neilowi.

Zaoszczędził kolejne 2 bajty dzięki Martinowi.

Usuwa nieliterowe litery, a następnie zamienia samogłoski na 1 i spółgłosek na 2, aby uzyskać spójne wartości. Następnie wielokrotnie usuwa pierwszy i ostatni znak, jeśli są one takie same. Kiedy już nie są, słowo było symetryczne, jeśli pozostał jeden lub zero znaków.


Czy \D 2praca pozwala Ci zaoszczędzić kilka bajtów T`lL`2?
Neil

@Neil Tak, wydaje się, ładny połów!
FryAmTheEggman

Dobra robota. Próbowałem to zrobić :(
Christopher

7

PHP, 82 bajty

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

Wypróbuj online!


Można poprzedzić rzutowania typów (bool)i wyjąć $s=i ==$ssprawdzić, aby zapisać 1 bajt.
kaiser

Jeśli się nie mylę, możesz zamienić na „ (bool)tylko 0||powiedzieć fałsz” lub… zamiast tego, oszczędzając 3 dodatkowe bajty.
kaiser

Hm Nie można użyć \wdo słownych znaków zamiast a-z?
kaiser

@kaiser \wzawiera cyfry podkreślenia i litery. To nie zadziała i [^/p{L}]jest dłuższe niż [^a-z]plus. Porównuję łańcuch odwrotny z łańcuchem, więc $sjest potrzebny do utworzenia wartości logicznej
Jörg Hülsermann

To prawda. Nadal inni powinni działać. „Powinni”… tak.
kaiser

6

MATL, 14 bajtów

t3Y2m)13Y2mtP=

Wypróbuj w MATL Online .

Oto nieco zmodyfikowana wersja, aby sprawdzić wszystkie przypadki testowe.

Wyjaśnienie

        % 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

Pokazujesz to za pomocą „Martin Ender” zamiast „Dennis”? muszę ponownie spojrzeć na tytuł wyzwania.
Roman Gräf

1
Przypuszczalnie Suever chciał demonstracji, która miała trochę filtrowania na pierwszym etapie.
Greg Martin

Następnie powinien użyć „Alex A.” zamiast tego ma też kropkę.
Erik the Outgolfer

2
Nie wiem, o co chodzi. Wybrałem Martina Endera, ponieważ byłoby prawdą, gdybyś usunął spacje, a fałsz inaczej.
Zamieściłem

6

Haskell, 84 75 74 69 bajtów

-10 dzięki @nimi
-5 dzięki @Zgarb

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

Zrozumienie listy zastępuje każdą literę logiczną i usuwa wszystkie inne znaki. Pierwsza część sprawdza, czy wynikowa lista jest palindromem.

Wypróbuj online!


Dwie wskazówki: 1) Zrozumienie listy jest często krótsze niż filterpo niej, mapnawet jeśli musisz przełączyć się na tryb wolny od poitfree. 2) <$>idJest zbyteczny. f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,celem ['A'..'Z']++['a'..'z']].
nimi

Możesz upuścić spację między ci "dla jeszcze jednego bajtu.
nimi

1
Myślę, że c`elem`['A'..'Z']++['a'..'z']można go skrócić do'@'<c,c<'{','`'<c||c<'['
Zgarb


4

Brachylog , 13 bajtów

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

Wypróbuj online!

Wyjaśnienie

ḷ                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

Alice , 28 bajtów

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

Wypróbuj online!

Rezultaty 1są prawdomówne, a nic nie jest fałszywe.

Wyjaśnienie

Każde polecenie w tym programie wykonuje się w trybie porządkowym, ale z lekkim zwrotem w szablonie, który pozwala mi zapisać bajt. Jeśli nowa linia jest akceptowalną wartością prawdziwości, mogę zapisać jeszcze jeden bajt tą samą metodą.

Zlinearyzowany program jest następujący:

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

Python 3 , 72 71 bajtów

-1 bajt dzięki @ovs

def f(s):s=[c in'AEIOU'for c in s.upper()if'@'<c<'['];return s==s[::-1]

Wypróbuj online!


def f(s):s=[c in'AEIOU'for c in s.upper()if'@'<c<'['];return s==s[::-1]dla 71 bajtów
ovs

3

JavaScript (ES6), 72 69 bajtów

Zaoszczędzono 3 bajty dzięki Neilowi

Zwraca wartość logiczną.

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

Przypadki testowe


Zaoszczędź kilka bajtów, zastępując 2 puste ciągi znakiem 2.
Kudłaty

1
Czy w ogóle potrzebujesz +''na końcu? To oszczędziłoby 3 bajty.
Neil

Bardziej podoba mi się pomysł @ Neila!
Kudłaty

2

Mathematica, 113 bajtów

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

Możesz pozbyć się kilku bajtów:PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
Nie ma drzewa

2

GolfScript , 42 bajty

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

Wypróbuj online!

Trudna część generuje zarówno wielkie, jak i małe litery w jednym ciągu, którego użyjemy w funkcji filtrowania, aby odfiltrować litery z wprowadzonego tekstu. Na szczęście, ponieważ ciągi znaków w GolfScript są tylko tablicami współrzędnych kodowych ze specjalną właściwością, dzięki czemu możemy po prostu generować te współrzędne w efektywny sposób. Oto jak je generujemy:

Najpierw generujemy zakres [0..122], przy czym 122 jest punktem kodowym dla z. Następnie bierzemy elementy od elementu o indeksie 65 wzwyż. 65 jest punktem kodowym dla A. W tej chwili mamy [65..122]. Wszystko w porządku, z wyjątkiem tego, że mamy tam trochę niechcianych współrzędnych kodowych ([91..96]). Najpierw tworzymy duplikat tego zakresu. Następnie bierzemy elementy od indeksu 26 i otrzymujemy [91..122]. Następnie otrzymujemy elementy aż do indeksu 5. Teraz mamy [91..96]. Na koniec usuwamy te elementy z naszego [65..122], pozostawiając nam wil [65..90, 97..122]. To są punkty kodowe, których chcemy.

Teraz, gdy stworzyliśmy górną / dolną listę kodową alfabetu, kontynuujemy naszą funkcję filtrowania. Funkcja jest odwzorowywana na każdy znak w ciągu wejściowym, który, jak początkowo powiedziałem, jest analizowany jako punkt kodowy. Więc teraz w zasadzie mamy [codepoint, [65..90, 97..122]]. Aby dowiedzieć się, czy char codepointjest literą, po prostu bierzemy jej indeks z utworzonej przez nas listy. Jeśli go nie ma, -1zamiast tego otrzymamy indeks.

W tej chwili otrzymujemy wartość falsey tylko wtedy codepoint == 65, gdy , tj. Pierwszy indeks naszej listy, ponieważ tylko wtedy indeks będzie wynosił 0. Ale pojedynczy przyrost rozwiąże ten problem, a teraz, jeśli codepointjest na naszej liście, będziemy dostajemy jego indeks + 1, który jest zawsze liczbą dodatnią, a zatem zawsze prawdziwą, a jeśli go nie ma, otrzymamy -1 + 1 = 0, tj. falsey.

W końcu stosujemy funkcję, którą opisałem, do każdego znaku wejściowego i pobieramy tylko znaki, dla których funkcja zwróciła prawdziwy wynik.

Następnie musimy ustalić, czy każdy znak jest samogłoską czy spółgłoską. Ponieważ samogłosek jest mniej niż spółgłosek, tworzenie ciągu samogłosek, dzięki czemu sprawdzamy, czy ten warunek jest krótszy niż tworzenie ciągu spółgłosek, więc sprawdzamy, czy każdy znak jest samogłoską. Aby jednak sprawdzić, czy lista wartości logicznych jest palindromiczna, potrzebujemy wartości logicznych, których nie otrzymujemy po prostu biorąc indeks + 1, ponieważ może to skutkować dowolną liczbą [1..10], jeśli char jest samogłoską. I, jak większość języków golfowych, ten też nie ma żadnej boolfunkcji. Po prostu używamy not not x, ponieważ notzawsze zwraca wartość logiczną. Ale poczekaj; czy naprawdę potrzebujemy konkretnych booleanów? Ponieważ notzawsze zwraca wartość logiczną, dlaczego po prostu nie usuwamy drugiegonoti faktycznie sprawdź, czy każdy znak jest spółgłoską? Tak, właśnie to zrobimy!

Po sprawdzeniu, które zwraca listę wartości logicznych, sprawdzamy, czy otrzymana przez nas lista wartości logicznych jest palindromem, o co prosi nas to wyzwanie. Jaka jest definicja palindromu? Tak, palindrom to lista lub ciąg znaków, który jest równy jego odwrotności. Jak więc sprawdzamy? Proste, powielamy go, robimy odwrotność i porównujemy z oryginalną listą. W rezultacie otrzymujemy to, wreszcie , co nasz kod powinien wrócić.


1
Olbrzymie wyjaśnienie dla 42-bajtowego programu. Teraz wydaje mi się, że jest to dość oczywiste ...
Erik the Outgolfer

2

PHP , 87 bajtów

Darmowa wersja PHP Regex. Dodano „samogłoskę”, ponieważ paski mogą zwracać 0, co w PHP jest fałszem.

Błąd naprawiony przez Jörga.

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

Wypróbuj online!


Ta sama liczba bajtów. for(;a&$c=$argn[$p++];)ctype_alpha($c)?$s.=stripos(_aeiou,$c)?0:1:0;echo$s==strrev($s);ale otrzyma właściwy wynik dla ciągów zawierających zero
Jörg Hülsermann

@ JörgHülsermann Dziękuję.
ME

2

q / kdb +, 42 38 bajtów

Rozwiązanie:

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

Przykład:

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

Wyjaśnienie:

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'

Edycje:

  • -4 bajty; przełączanie reversena k równoważnika|:

2

CJam , 26 bajtów

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

Wypróbuj online!

-1 dzięki Esolanging Fruit .


Można wymienić 26,'af+z '{,97>zapisać bajt.
Esolanging Fruit

@EsolangingFruit taka stara odpowiedź ...
Erik the Outgolfer

Bajt zapisany pół roku temu nie różni się od bajtu zapisanego teraz. To nie jest tak, że występuje inflacja bajtów lub coś w tym stylu: P
Esolanging Fruit

@EsolangingFruit Odniosłem się do moich stale rozwijających się doświadczeń z golfem ... oczywiście masz kredyt jak zwykle, nie martw się!
Erik the Outgolfer

2

Braingolf,  4  3 bajty

&JP

-1 bajt dzięki Erik the Outgolfer

Okazuje się, że miałem je Pcały czas, nawet przed tym wyzwaniem.

J jednak, mimo że został stworzony przed tym wyzwaniem, nie został zepchnięty na github przed wyzwaniem, dlatego nadal nie konkuruje.

Wyjaśnienie:

&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

Dlaczego musisz n?
Erik the Outgolfer

@EriktheOutgolfer, ponieważ jestem certyfikowanym kretynem
Skidsdev

Hmm, zapomniałeś usunąć go z wyjaśnienia.
Erik the Outgolfer

@EriktheOutgolfer Byłem gunna, napisałem „Erick”, a następnie wykreślono literę c, ale po prostu wygląda jak „Eriek”
Skidsdev

Czy to nie zawiedzie takich jak Alex A.?
Kudłaty

1

Python 2, 83 bajty

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

Definiuje funkcję, która daje TruealboFalse


Możesz zapisać 2 bajty, używając "aeiouAEIOU".__contains__zamiast lambda y:y.lower()in"aeiou".
Blender




1

Bash , 82 bajty

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

Wypróbuj online!

Pobiera nazwę jako parametr, usuwa litery nie będące literami, zamienia samogłoski na 0, nie samogłosek i 0 na 1 i porównuje z tym samym odwróconym.

Mógłby grać w golfa więcej, jeśli może dostać podwójną lub potrójną zmianę

Status wyjścia to 0 dla prawdy i 1 dla nie.


W najnowszych wersjach bash i=${i^^*};konwertuje ina wielkie litery. Ale myślę, że to tylko oszczędza ci a-zoraz aeiou, co jest mniej niż 10B to kosztuje.
Peter Cordes

1

Japt v2.0a0, 19 11 bajtów

k\L mè\v ê¬

Wypróbuj online


Wyjaśnienie

        :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

PowerShell, 108 bajtów

read-host|%{[char[]]$_|%{$d=$_-replace'\P{L}'-replace'[aeiou]',0-replace'\D',1;$s="$s$d";$r="$d$r"};$s-eq$r}

0

Aksjomat, 126 bajtów

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))

test

(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 bajtów

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

Uzyskaj kopię ciągu, w którym samogłoski mają wartość 0, a spółgłoski mają wartość 1, po usunięciu wszystkich znaków specjalnych, porównaj ten ciąg z wersją odwróconą połączoną z powrotem z ciągiem znaków

Wynik:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.