User Appreciation Challenge # 1: Dennis ♦


53

Ich kam spontan auf die Idee, eine Reihe von Herausforderungen an Benutzer zu stellen, die dazu beigetragen haben, dass die PPCG-Community für alle oder nur für mich ein angenehmer Ort ist. : P

Wenn Sie den Namen von Dennis in ein Array von 1s und 0s konvertieren, in dem sich jeder Konsonant 1und jeder Vokal befindet 0, ist das Array [1, 0, 1, 1, 0, 1]symmetrisch. Daher besteht Ihre Herausforderung darin, festzustellen, welche anderen Namen dies sind.

Herausforderung

Entfernen Sie bei einer vorgegebenen ASCII-Zeichenfolge alle Zeichen, die keine Buchstaben sind, und stellen Sie fest, ob die Konfiguration von Vokalen und Konsonanten symmetrisch ist. yist kein Vokal.

Bitte beachten Sie, dass es sich bei Ihrem Programm nicht unbedingt um einen solchen String handeln muss.

Testfälle

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

Referenzimplementierung

Dieser Python 3-Code gibt in einem Testfall die richtige Ausgabe aus. Es ist so unrühmlich, wie ich es schaffen könnte, ohne lächerlich zu sein.

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

Probieren Sie es online!


Wann und wer ist die Nummer 2?
Caird Coinheringaahing

@cairdcoinheringaahing Danke, dass du mich daran erinnert hast. Es wird um Mego gehen (TNB RO, daher kursiv), aber ich bin noch nicht dazu gekommen, es zu finalisieren.
HyperNeutrino

Soll ich es ihm sagen oder würde er einfach ins Wasser tauchen, um nach Fischen zu suchen?
Caird Coinheringaahing

@cairdcoinheringaahing Ich bin mir ziemlich sicher, dass er es bereits weiß; Ich sagte, ich würde einen gegen ihn machen, aber ich habe noch nicht entschieden, ob ich noch etwas in Bezug auf Pinguine oder TNB machen werde.
HyperNeutrino

Ich rechne mit Pinguinen. Es ist das, wofür er weiß (für mich)
Caird Coinheringaahing

Antworten:


15

05AB1E , 9 Bytes

žM¹álSåÂQ

Probieren Sie es online!

-2 danke an Adnan .

Dies greift Jellys Schmerzpunkt genau an. Es verwendet lund A1-Byte - Äquivalente für Jelly Œlund Øajeweils.


Sind Sie sicher, dass das funktioniert? Führen Sie diese
MCCCS

@MCCCS Hmm, vielleicht hast du recht.
Erik der Outgolfer

Sie können nach áund DRnach ersetzen Â.
Adnan

@Adnan Vergessen á, wusste nicht was Â, danke!
Erik der Outgolfer

11
@alexis die meisten dieser Golf Sprachen verwenden 256 verschiedene Zeichen und eine benutzerdefinierte Codepage , die Hex - Karten 00zu FFjenen 256 Zeichen finden Sie in der Antwort Jelly
Stephen

18

Jelly , 11 Bytes

ŒufØAe€ØCŒḂ

Probieren Sie es online!

Alternative Versionen:

ŒlfØae€ØCŒḂ

ŒufØAe€ØcŒḂ

ŒlfØae€ØcŒḂ

Natürlich muss eine Herausforderung, die Dennis schätzt, eine Antwort in einer seiner Sprachen haben.


15
Œuf is Egg auf französisch. Einfach sagen
YSC

13

x86-32-Bit-Maschinencodefunktion, 42 bis 41 Byte

Derzeit die kürzeste Antwort in einer anderen Sprache als Golf, 1B kürzer als @ streetsters q / kdb + .

Mit 0 für wahr und ungleich Null für falsch: 41 40 Bytes. (Speichert im Allgemeinen 1 Byte für 32-Bit, 2 Byte für 64-Bit).

Mit Zeichenfolgen mit impliziter Länge (C-terminiert mit 0): 45 44 Bytes

x86-64-Maschinencode (mit 32-Bit-Zeigern wie dem x32-ABI): 44 43 Byte .

x86-64 mit Zeichenfolgen impliziter Länge, immer noch 46 Byte (die Shift / Mask-Bitmap-Strategie ist jetzt ausgeglichen).

Dies ist eine Funktion mit C-Signatur _Bool dennis_like(size_t ecx, const char *esi). Die Aufrufkonvention ist etwas ungewöhnlich und liegt in der Nähe von MS Vectorcall / Fastcall, weist jedoch unterschiedliche Arg-Register auf: String in ESI und Länge in ECX. Es blockiert nur seine Argumente und EDX. AL enthält den Rückgabewert, wobei die hohen Bytes Garbage enthalten (wie in den SysV x86- und x32-ABIs zulässig). IDK, was die ABIs von MS zu High-Garbage sagen, wenn Bool oder enge Ganzzahlen zurückgegeben werden.


Erklärung des Algorithmus :

Durchlaufen Sie die Eingabezeichenfolge, filtern und klassifizieren Sie sie in ein boolesches Array auf dem Stapel: Prüfen Sie für jedes Byte, ob es sich um ein alphabetisches Zeichen handelt (falls nicht, fahren Sie mit dem nächsten Zeichen fort), und wandeln Sie es in eine Ganzzahl von 0-25 (AZ) um. . Verwenden Sie diese 0-25-Ganzzahl, um eine Bitmap von Vokal = 0 / Konsonant = 1 zu überprüfen. (Die Bitmap wird als 32-Bit-Sofortkonstante in ein Register geladen.) Schieben Sie 0 oder 0xFF auf den Stapel entsprechend dem Bitmap-Ergebnis (tatsächlich im Low-Byte eines 32-Bit-Elements, das möglicherweise in den oberen 3 Bytes Müll enthält).

Die erste Schleife erzeugt ein Array von 0 oder 0xFF (in mit Garbage aufgefüllten Dword-Elementen). Führen Sie die übliche Palindromprüfung mit einer zweiten Schleife durch, die anhält, wenn sich die Zeiger in der Mitte kreuzen (oder wenn beide auf dasselbe Element zeigen, wenn eine ungerade Anzahl alphabetischer Zeichen vorhanden ist). Der sich nach oben bewegende Zeiger ist der Stapelzeiger, und wir verwenden POP zum Laden + Inkrementieren. Anstelle von compare / setcc in dieser Schleife können wir nur XOR verwenden, um dasselbe / unterschiedliches zu erkennen, da es nur zwei mögliche Werte gibt. Wir könnten (mit OR) akkumulieren, ob wir nicht passende Elemente gefunden haben, aber ein Early-Out-Zweig für Flags, die von XOR gesetzt wurden, ist mindestens genauso gut.

Beachten Sie, dass die zweite Schleife die byteOperandengröße verwendet , sodass es egal ist, welchen Abfall die erste Schleife außerhalb des Low-Bytes jedes Array-Elements hinterlässt.


Es verwendet den undokumentierten salcBefehl , um AL von CF auf die gleiche Weise zu setzen, wie dies der Fall sbb al,alwäre. Es wird von jeder Intel-CPU unterstützt (außer im 64-Bit-Modus), sogar von Knight's Landing! Agner Fog listet das Timing auch für alle AMD-CPUs (einschließlich Ryzen) auf. Wenn also x86-Anbieter darauf bestehen, dieses Byte Opcode-Speicherplatz seit 8086 zu belegen, können wir es auch nutzen.

Interessante Tricks:

  • Unsigned -Compare-Trick für eine Kombination aus isalpha () und toupper () und Null-Erweiterung des Bytes, um eax zu füllen, mit folgenden Einstellungen:
  • sofortige Bitmap in einem Register für bt, inspiriert von einer netten Compiler-Ausgabe fürswitch .
  • Erstellen eines Arrays mit variabler Größe auf dem Stapel durch Drücken einer Schleife. (Standard für asm, aber nichts, was Sie mit C für die String-Version mit impliziter Länge tun können). Für jedes eingegebene Zeichen werden 4 Byte Stapelspeicherplatz benötigt, es wird jedoch mindestens 1 Byte im Vergleich zum optimalen Golfspiel gespart stosb.
  • Anstelle von cmp / setne auf dem Booleschen Array werden XOR-Boolesche Werte zusammengefasst, um direkt einen Wahrheitswert zu erhalten. ( cmp/ salcist keine Option, da salcnur für CF funktioniert und 0xFF-0 CF nicht festlegt. Ist sete3 Bytes, würde aber die incexterne Schleife vermeiden , bei einem Nettokosten von 2 Bytes (1 im 64-Bit-Modus) )) vs. xor in the loop und fixieren mit 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

Dies ist wahrscheinlich auch eine der schnellsten Antworten, da keines der Golfspiele wirklich zu weh tut, zumindest für Zeichenfolgen mit weniger als ein paar tausend Zeichen, bei denen die 4x-Speichernutzung nicht viele Cache-Fehlschläge verursacht. (Es kann auch vorkommen, dass Antworten verloren gehen, die für nicht Dennis-ähnliche Zeichenfolgen vorzeitig beendet werden, bevor alle Zeichen durchlaufen werden .) Ist salclangsamer als setccbei vielen CPUs (z. B. 3 Uops vs. 1 bei Skylake), aber eine Bitmap-Überprüfung mit bt/salcist immer noch schneller als eine String-Suche oder ein Regex-Match. Und es gibt keinen Start-Overhead, daher ist es für kurze Streicher extrem billig.

Dies in einem Durchgang zu tun, würde bedeuten, den Klassifizierungscode für die Aufwärts- und Abwärtsrichtung zu wiederholen. Das wäre schneller, aber größer. (Wenn Sie schnell sein wollen, können Sie mit SSE2 oder AVX2 natürlich 16 oder 32 Zeichen gleichzeitig machen, wobei Sie den Compare-Trick weiterhin anwenden, indem Sie den Bereich an den unteren Rand des vorzeichenbehafteten Bereichs verschieben.)


Testen Sie das Programm (für ia32 oder x32 Linux) , um diese Funktion mit einem cmdline-Argument aufzurufen, und beenden Sie es mit status = return value. strlenImplementierung von 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

Eine 64-Bit-Version dieser Funktion könnte verwenden sbb eax,eax, die nur 2 Bytes anstelle von 3 für ist setc al. Es würde auch ein zusätzliches Byte für decoder notam Ende benötigen (da nur 32-Bit 1-Byte-Inc / Dec-R32 hat). Mit dem x32-ABI (32-Bit-Zeiger im langen Modus) können wir REX-Präfixe immer noch vermeiden, obwohl wir Zeiger kopieren und vergleichen.

setc [rdi]kann direkt in den Speicher schreiben, aber das Reservieren von ECX-Bytes Stapelspeicher kostet mehr Code als das spart. (Und wir müssen uns durch das Ausgabearray bewegen. Benötigt [rdi+rcx]ein zusätzliches Byte für den Adressierungsmodus, aber wirklich brauchen wir einen Zähler, der für gefilterte Zeichen nicht aktualisiert wird, also wird es schlimmer sein.)


Dies ist die YASM / NASM-Quelle mit %ifBedingungen. Es kann mit -felf32(32-Bit-Code) oder -felfx32(64-Bit-Code mit dem x32-ABI) und mit impliziter oder expliziter Länge erstellt werden . Ich habe alle 4 Versionen getestet. In dieser Antwort finden Sie ein Skript zum Erstellen einer statischen Binärdatei aus einer NASM / YASM-Quelle.

Um die 64-Bit-Version auf einem Computer ohne Unterstützung für das x32-ABI zu testen, können Sie die Zeigerregs in 64-Bit ändern. (Dann subtrahieren Sie einfach die Anzahl der REX.W = 1-Präfixe (0x48 Byte) von der Anzahl. In diesem Fall benötigen 4 Befehle REX-Präfixe, um mit 64-Bit-Registern zu arbeiten.) Oder rufen Sie es einfach mit dem rspund dem Eingabezeiger im niedrigen 4G-Adressraum auf.

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

Ich habe versucht, mit DF (der Richtungsfahne, die lodsd/ scasdund so weiter steuert ) herumzuspielen , aber es schien einfach kein Gewinn zu sein. Die üblichen ABIs erfordern, dass DF beim Funktionseintritt und -austritt gelöscht wird. Angenommen, beim Betreten gelöscht, aber beim Verlassen gesetzt, wäre Betrug, IMO. Es wäre schön, LODSD / SCASD zu verwenden, um die 3-Byte-Größe zu vermeiden sub esi, 4, insbesondere in Fällen, in denen kein hoher Müll vorhanden ist.


Alternative Bitmap-Strategie (für Zeichenfolgen mit impliziter Länge von x86-64)

Es stellt sich heraus, dass dies keine Bytes spart, da es bt r32,r32immer noch mit hohem Müll im Bit-Index funktioniert. Es ist einfach nicht dokumentiert, wie es shrist.

bt / sbbVerwenden Sie eine Verschiebung / Maske, um das gewünschte Bit von der Bitmap zu isolieren, anstatt das Bit in die / aus der CF zu holen.

%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

Da dies in AL am Ende 0/1 ergibt (statt 0 / 0xFF), können wir die notwendige Invertierung des Rückgabewerts am Ende der Funktion mit xor al, 1(2B) statt dec eax(auch 2B in x86-64) durchführen erzeugen immer noch einen richtigen bool/_Bool Rückgabewert.

Dadurch wurde 1B für x86-64 mit Zeichenfolgen impliziter Länge eingespart, da die hohen Bytes von EAX nicht auf Null gesetzt werden müssen. (Früher habe ich and eax, 0x7F ^ 0x20den Rest von eax mit einem 3-Byte-Code in Großbuchstaben geschrieben und auf Null gesetzt and r32,imm8. Jetzt verwende ich jedoch die 2-Byte-Sofort-mit-AL-Codierung, die die meisten 8086-Befehle haben, wie ich es bereits getan habe für die subund cmp.)

Es verliert an bt/ salcin 32-Bit - Modus, und explizite Zeichenfolge der Länge benötigen ECX für die Zählung so ist dies dort entweder nicht funktionieren.

Aber dann habe ich gemerkt, dass ich mich geirrt habe: arbeitet bt edx, eaximmer noch mit Hochmüll in eax. Es scheint Masken der Verschiebung zählen die gleiche Art und Weise shr r32, clnicht (nur auf der Suche bei dem niedrigen 5 Bits cl). Dies unterscheidet sich davon bt [mem], reg, dass der Zugriff außerhalb des Speichers, auf den durch den Adressierungsmodus / die Adressierungsgröße verwiesen wird, als Bitstring behandelt werden kann. (Crazy CISC ...)

Intels Insn-Set-Ref-Handbuch dokumentiert die Maskierung nicht. Daher ist es möglicherweise undokumentiertes Verhalten, das Intel derzeit beibehält. (So ​​etwas ist nicht ungewöhnlich. bsf dst, srcMit src = 0 bleibt dst immer unverändert, auch wenn dokumentiert ist, dass dst in diesem Fall einen undefinierten Wert enthält. AMD dokumentiert tatsächlich das Verhalten von src = 0.) Ich habe es mit Skylake und Core2 getestet. und die btVersion arbeitet mit nicht-Null-Müll in EAX außerhalb von AL.

Ein guter Trick ist hier xchg eax,ecx(1 Byte), um die Zählung in CL zu bekommen. Leider ist BMI2 shrx eax, edx, eax5 Bytes , verglichen mit nur 2 Bytes für shr eax, cl. Für die Verwendung wird bextrein 2-Byte-Wert mov ah,1(für die Anzahl der zu extrahierenden Bits) benötigt, daher sind es wieder 5 + 2 Byte wie bei SHRX + AND.


Der Quellcode ist nach dem Hinzufügen von %ifBedingungen ziemlich chaotisch geworden . Hier ist das Zerlegen von x32-Zeichenfolgen mit impliziter Länge (unter Verwendung der alternativen Strategie für die Bitmap, also immer noch 46 Byte).

Der Hauptunterschied zur expliziten Länge liegt in der ersten Schleife. Beachten Sie, wie es ein lodsdavor und am unteren Rand gibt, anstatt nur eines am oberen Rand der Schleife.

    ; 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

Netzhaut ,49 47 45 Bytes

\P{L}

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

Probieren Sie es online!

2 Bytes gespart dank Neil.

Weitere 2 Bytes dank Martin gespeichert.

Entfernt Nichtbuchstaben und ersetzt Vokale durch 1 und Konsonanten durch 2, um konsistente Werte zu erhalten. Entfernt dann wiederholt das erste und das letzte Zeichen, wenn sie gleich sind. Wenn dies nicht der Fall ist, war das Wort symmetrisch, wenn noch ein oder null Zeichen übrig sind.


Spart \D 2Ihnen die Arbeit ein paar Bytes T`lL`2?
Neil

@Neil Ja es scheint, schöner Fang!
FryAmTheEggman

Gut gemacht. Ich habe versucht, dies zu tun :(
Christopher

7

PHP, 82 Bytes

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

Probieren Sie es online!


Sie können der Typumwandlung voranstellen und das Häkchen (bool)und entfernen , um 1 Byte zu sparen. $s===$s
Kaiser

Wenn ich nicht irre, könnte ersetzen Sie das (bool)mit nur 0||zu sagen , falsch, oder ... stattdessen Speichern 3 weitere Bytes.
Kaiser

Hm. Könnten Sie nicht \wfür Wortzeichen anstelle von verwenden a-z?
Kaiser

@kaiser \wenthält Ziffern, Unterstriche und Buchstaben. Dies wird nicht funktionieren und [^/p{L}]ist länger als [^a-z]plus i. Ich vergleiche die umgekehrte Zeichenfolge mit der Zeichenfolge, $sdie zum Erstellen des Booleschen erforderlich ist
Jörg Hülsermann,

Das ist wahr. Trotzdem sollten die anderen funktionieren. "Sollte" ... tun sie.
Kaiser

6

MATL, 14 Bytes

t3Y2m)13Y2mtP=

Probieren Sie es bei MATL Online aus .

Hier ist eine leicht modifizierte Version, um alle Testfälle zu überprüfen.

Erläuterung

        % 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

Sie demonstrieren es mit "Martin Ender" anstelle von "Dennis"? Ich muss mir den Titel der Herausforderung noch einmal ansehen.
Roman Gräf

1
Vermutlich wollte Suever eine Demonstration, die im ersten Schritt etwas Filterung aufwies.
Greg Martin

Dann sollte er "Alex A." Stattdessen hat es auch eine Periode.
Erik der Outgolfer

2
Ich bin verwirrt, worum es geht. Ich habe mich für Martin Ender entschieden, weil es tatsächlich wahr wäre, wenn Sie Leerzeichen entfernen und ansonsten falsch. Ich habe auch einen Link zu allen Testfällen
eingefügt

6

Haskell, 84 75 74 69 Bytes

-10 danke an @nimi
-5 danke an @Zgarb

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

Das Listenverständnis ersetzt jeden Buchstaben durch einen Booleschen Wert und entfernt alle anderen Zeichen. Der erste Teil prüft, ob die resultierende Liste ein Palindrom ist oder nicht.

Probieren Sie es online!


Zwei Tipps: 1) Ein Listenverständnis ist oft kürzer als das filterfolgende, mapauch wenn Sie nicht poitfrei wechseln müssen. 2) Das <$>idist überflüssig. f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,celem ['A'..'Z']++['a'..'z']].
nimi

Sie können den Abstand zwischen cund "für ein weiteres Byte löschen.
nimi

1
Ich denke, c`elem`['A'..'Z']++['a'..'z']kann auf'@'<c,c<'{','`'<c||c<'['
Zgarb


4

Brachylog , 13 Bytes

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

Probieren Sie es online!

Erläuterung

ḷ                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 Bytes

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

Probieren Sie es online!

Ausgaben 1als wahr und nichts als falsch.

Erläuterung

Jeder Befehl in diesem Programm wird im Ordnungsmodus ausgeführt, jedoch mit einer leichten Drehung in der Vorlage, mit der ich ein Byte speichern kann. Wenn ein Zeilenumbruch ein akzeptabler Wahrheitswert ist, kann ich mit derselben Methode ein weiteres Byte speichern.

Linearisiert sieht das Programm wie folgt aus:

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 bis 69 Byte

3 Bytes gespart dank Neil

Gibt einen Booleschen Wert zurück.

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

Testfälle


Speichern Sie ein paar Bytes, indem Sie die 2 leeren Zeichenfolgen durch ersetzen 2.
Shaggy

1
Benötigst du das +''überhaupt zum Schluss? Das würde stattdessen 3 Bytes einsparen.
Neil

Mir gefällt die Idee von @ Neil besser!
Shaggy

2

Mathematica, 113 Bytes

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

Sie können einige Bytes loswerden:PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
Kein Baum

2

GolfScript , 42 Bytes

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

Probieren Sie es online!

Der schwierige Teil besteht darin, sowohl das Groß- als auch das Kleinbuchstaben in einer Zeichenfolge zu generieren, die wir in einer Filterfunktion verwenden, um die Buchstaben aus der Eingabe herauszufiltern. Zum Glück, da Strings in GolfScript nur Codepoint-Arrays mit einer speziellen Eigenschaft sind, können wir die Codepoints nur auf effiziente Weise generieren. So generieren wir sie:

Zunächst erzeugen wir den Bereich [0..122], wobei 122 der Codepunkt für ist z. Dann nehmen wir die Elemente vom Element bei Index 65 ab. 65 ist der Codepunkt für A. Im Moment haben wir [65..122]. Alles in Ordnung, bis auf einige unerwünschte Codepunkte ([91..96]). Also machen wir zuerst ein Duplikat dieses Bereichs. Dann nehmen wir die Elemente ab Index 26 und haben [91..122]. Danach erhalten wir die Elemente bis einschließlich Index 5. Jetzt haben wir [91..96]. Schließlich entfernen wir diese Elemente aus unserem [65..122] und verlassen uns auf [65..90, 97..122]. Das sind die Codepunkte, die wir wollen.

Nachdem wir die obere / untere Alphabet-Codepunktliste erstellt haben, setzen wir unsere Filterfunktion fort. Die Funktion wird jedem Zeichen in der Eingabezeichenfolge zugeordnet, die stattdessen, wie eingangs erwähnt, als Codepunkt analysiert wird. Also haben wir jetzt im Wesentlichen [codepoint, [65..90, 97..122]]. Um herauszufinden, ob char codepointein Buchstabe ist, nehmen wir einfach seinen Index in die Liste, die wir erstellt haben. Wenn es nicht da ist, werden wir -1stattdessen als Index erhalten.

Im Moment erhalten wir nur dann einen Falsey-Wert, wenn codepoint == 65, dh der erste Index unserer Liste, nur dann der Index 0 wäre. Dieses Problem wird jedoch durch ein einzelnes Inkrement behoben, und wenn dies codepointin unserer Liste enthalten ist, werden wir es tun Holen Sie sich den Index + 1, der immer eine positive Zahl ist, also immer wahrheitsgemäß. Wenn er nicht vorhanden ist, erhalten Sie -1 + 1 = 0, dh falsch.

Schließlich wenden wir die von mir beschriebene Funktion auf jedes Zeichen der Eingabe an und nehmen nur die Zeichen, für die die Funktion ein wahres Ergebnis zurückgegeben hat.

Als nächstes müssen wir feststellen, ob jedes Zeichen ein Vokal oder ein Konsonant ist. Da die Vokale kleiner sind als die Konsonanten, ist das Erstellen einer Folge von Vokalen, damit wir auf diese Bedingung prüfen, kürzer als das Erstellen einer Folge von Konsonanten, sodass wir prüfen, ob jedes Zeichen ein Vokal ist. Um jedoch zu überprüfen, ob die Boolesche Liste palindrom ist, benötigen wir Boolesche Werte, die wir nicht nur durch Verwendung des Index + 1 erhalten, da dies zu einer beliebigen Anzahl von [1..10] führen kann, wenn das Zeichen ein Vokal ist. Und wie die meisten Golfsprachen hat auch diese keine boolFunktion. Also verwenden wir einfach not not x, da notimmer ein Boolescher Wert zurückgegeben wird. Aber warte; Müssen wir wirklich bestimmte Boolesche Werte haben? Da notimmer ein Boolescher Wert zurückgegeben wird, entfernen wir einfach den zweitennot, und tatsächlich prüfen, ob jedes Zeichen ein Konsonant ist? Ja, genau das werden wir tun!

Nach der Prüfung, die eine Liste von Booleschen Werten zurückgibt, prüfen wir, ob diese erhaltene Boolesche Liste ein Palindrom ist. Dazu werden wir bei dieser Herausforderung aufgefordert. Was ist die Definition eines Palindroms? Ja, ein Palindrom ist eine Liste oder Zeichenfolge, die der Umkehrung entspricht. Wie überprüfen wir das? Ganz einfach, wir duplizieren es, machen es umgekehrt und vergleichen es mit der ursprünglichen Liste. Das Ergebnis ist schließlich , was unser Code zurückgeben soll.


1
Riesige Erklärung für ein 42-Byte-Programm. Jetzt denke ich, dass es ziemlich selbsterklärend ist ...
Erik the Outgolfer

2

PHP , 87 Bytes

Regex kostenlose PHP-Version. Ein "Vokal" wurde hinzugefügt, da Stripos 0 zurückgeben können, was in PHP falsch ist.

Fehler behoben von Jörg.

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

Probieren Sie es online!


Gleiche Bytezahl. for(;a&$c=$argn[$p++];)ctype_alpha($c)?$s.=stripos(_aeiou,$c)?0:1:0;echo$s==strrev($s);aber es wird das richtige Ergebnis für Zeichenfolgen, die Null enthalten
Jörg Hülsermann

@ JörgHülsermann Danke.
ME

2

q / kdb +, 42 38 Bytes

Lösung:

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

Beispiel:

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

Erläuterung:

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'

Bearbeitungen:

  • -4 Bytes; Ausschalten reversefür k Äquivalent|:

2

CJam , 26 Bytes

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

Probieren Sie es online!

-1 dank Esolanging Fruit .


Sie können ersetzen 26,'af+mit '{,97>einem Byte zu speichern.
Esolanging Fruit

@ EsolangingFruit so eine alte Antwort ...
Erik der Outgolfer

Ein Byte, das vor einem halben Jahr gespeichert wurde, unterscheidet sich nicht von einem Byte, das jetzt gespeichert wurde. Es ist nicht so, als gäbe es eine Byte-Inflation oder so etwas: P
Esolanging Fruit

@EsolangingFruit Ich bezog mich auf meine sich ständig weiterentwickelnde Erfahrung mit dem Golfen ... natürlich hast du wie immer einen Kredit, keine Sorge!
Erik der Outgolfer

2

Braingolf,  4  3 Bytes

&JP

-1 Byte danke an Erik den Outgolfer

Es stellte sich heraus, dass ich die Pganze Zeit schon vor dieser Herausforderung war.

J Obwohl sie vor dieser Herausforderung erstellt wurden, wurden sie vor der Herausforderung nicht zum Github gezwungen und sind daher immer noch nicht konkurrierend.

Erläuterung:

&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

Warum brauchen Sie n?
Erik der Outgolfer

@EriktheOutgolfer, weil ich ein zertifizierter Idiot bin
Skidsdev

Hmm, du hast vergessen, es aus der Erklärung zu entfernen.
Erik der Outgolfer

@EriktheOutgolfer Ich war gunna schreiben "Erick", dann streichen Sie die c, aber es sieht aus wie "Eriek"
Skidsdev

Scheitert das nicht für Leute wie Alex A.?
Shaggy

1

Python 2, 83 Bytes

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

Definiert eine Funktion, die entweder Trueoder gibtFalse


Sie können 2 Bytes sparen, indem Sie "aeiouAEIOU".__contains__anstelle von verwenden lambda y:y.lower()in"aeiou".
Blender




1

Bash , 82 Bytes

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

Probieren Sie es online!

Erhält den Namen als Parameter, entfernt Nicht-Buchstaben, ersetzt Vokale durch 0, Nicht-Vokale noch 0 durch 1 und vergleicht diese umgekehrt.

Könnte ein bisschen mehr Golf spielen, wenn es um die doppelte oder dreifache Substitution geht

Der Beendigungsstatus ist 0 für wahr und 1 für nein.


i=${i^^*};Konvertiert iin neueren Bash-Versionen in Großbuchstaben. Aber ich denke, es spart dir nur ein a-zund ein aeiou, was weniger ist als die 10B, die es kostet.
Peter Cordes

1

Japt v2.0a0, 19 11 Bytes

k\L mè\v ê¬

Probieren Sie es online aus


Erläuterung

        :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 Byte

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

0

Axiom, 126 Bytes

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

Prüfung

(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 Bytes

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

Holen Sie sich eine Kopie der Zeichenfolge, in der Vokale 0 und Konsonanten 1 sind, und vergleichen Sie diese Zeichenfolge mit einer umgekehrten Version, die mit einer Zeichenfolge verknüpft ist, wobei alle Sonderzeichen entfernt sind

Ausgabe:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.