Sfida di apprezzamento dell'utente n. 1: Dennis ♦


53

Ho avuto l'idea spontanea di fare una serie di sfide per gli utenti che hanno aiutato e continuano ad aiutare la comunità PPCG ad essere un posto piacevole per tutti, o forse solo per me. : P

Se si converte il nome di Dennis ad una serie di 1s e 0s dove ogni consonante è 1e ogni vocale è 0, l'array è [1, 0, 1, 1, 0, 1], che è simmetrica. Pertanto, la tua sfida è determinare quali altri nomi sono così.

Sfida

Data una stringa ASCII, rimuovere tutti i caratteri che non sono lettere e determinare se la configurazione di vocali e consonanti è simmetrica. ynon è una vocale.

Si noti che il programma non deve essere questo tipo di stringa stesso.

Casi test

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

Implementazione di riferimento

Questo codice Python 3 fornirà l'output corretto dato un caso di test. È il meno possibile che potrei farcela senza essere ridicolo.

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

Provalo online!


Quando e chi è il n. 2?
caird coinheringaahing il

@cairdcoinheringaahing Grazie per avermelo ricordato. Si tratterà di Mego (TNB RO quindi del corsivo) ma non sono ancora riuscito a finalizzarlo.
HyperNeutrino,

dovrei dirglielo o si tufferebbe semplicemente in acqua per cercare pesce?
caird coinheringaahing

@cairdcoinheringaahing Sono abbastanza sicuro che lo sappia già; Ho detto che avrei fatto uno con lui, ma non ho ancora deciso se avrò fatto qualcosa relativo ai pinguini o al TNB.
HyperNeutrino,

Credo che i pinguini. È quello che sa (per me)
caird coinheringaahing il

Risposte:


15

05AB1E , 9 byte

žM¹álSåÂQ

Provalo online!

-2 grazie ad Adnan .

Questo attacca esattamente il punto dolente di Jelly. Usa le A, 1 byte equivalenti per Jelly Œle Øarispettivamente.


Sei sicuro che funzioni? Esegui questo
MCCCS

@MCCCS Hmm, potresti avere ragione.
Erik the Outgolfer,

È possibile sostituire entro áe DRper Â.
Adnan,

@Adnan Dimenticato á, non sapevo cosa Â, grazie!
Erik the Outgolfer,

11
@alexis la maggior parte di queste lingue di golf usano 256 caratteri diversi e una tabella codici personalizzati che mappa esagonale 00a FFquei 256 caratteri, vedere la risposta Jelly
Stephen

18

Gelatina , 11 byte

ŒufØAe€ØCŒḂ

Provalo online!

Versioni alternative:

ŒlfØae€ØCŒḂ

ŒufØAe€ØcŒḂ

ŒlfØae€ØcŒḂ

Naturalmente una sfida che apprezza Dennis deve avere una risposta in una sua lingua.


15
Isuf è Egg in francese. Dico solo
YSC,

13

x86 Funzione codice macchina a 32 bit, 42 41 byte

Attualmente la risposta in lingua non golf più breve, 1 B più breve di q / kdb + di @ streetster .

Con 0 per la verità e diverso da zero per la falsità: 41 40 byte. (in generale, salva 1 byte per 32 bit, 2 byte per 64 bit).

Con stringhe a lunghezza implicita (stile C con terminazione 0): 45 44 byte

codice macchina x86-64 (con puntatori a 32 bit, come l'ABI x32): 44 43 byte .

x86-64 con stringhe a lunghezza implicita, ancora 46 byte (la strategia bitmap shift / maschera è ora in pareggio).

Questa è una funzione con la firma C _Bool dennis_like(size_t ecx, const char *esi). La convenzione di chiamata è leggermente non standard, vicina a MS vectorcall / fastcall ma con diversi registri arg: stringa in ESI e lunghezza in ECX. Limita solo i suoi arg-reg e EDX. AL contiene il valore di ritorno, con i byte alti che trattengono la spazzatura (come consentito dalle ABI SysV x86 e x32. IDK cosa dicono le ABI di MS su high-garbage quando restituiscono valori bool o interi stretti).


Spiegazione dell'algoritmo :

Passa sopra la stringa di input, filtra e classifica in un array booleano nello stack: per ogni byte, controlla se si tratta di un carattere alfabetico (in caso contrario, continua con il carattere successivo) e trasformalo in un numero intero compreso tra 0 e 25 (AZ) . Usa quell'intero 0-25 per controllare una bitmap di vocale = 0 / consonante = 1. (La bitmap viene caricata in un registro come costante immediata a 32 bit). Spingere 0 o 0xFF sullo stack in base al risultato bitmap (in realtà nel byte basso di un elemento a 32 bit, che può contenere immondizia nei primi 3 byte).

Il primo ciclo produce un array di 0 o 0xFF (in elementi dword riempiti con immondizia). Esegui il solito controllo del palindromo con un secondo ciclo che si interrompe quando i puntatori si incrociano nel mezzo (o quando entrambi puntano allo stesso elemento in presenza di un numero dispari di caratteri alfabetici). Il puntatore verso l'alto è il puntatore dello stack e usiamo POP per caricare + incremento. Invece di compare / setcc in questo loop, possiamo semplicemente usare XOR per rilevare lo stesso / diverso poiché ci sono solo due valori possibili. Potremmo accumulare (con OR) se avessimo trovato elementi non corrispondenti, ma almeno un ramo iniziale sulle bandiere impostato da XOR è altrettanto buono.

Si noti che il secondo ciclo utilizza bytedimensioni dell'operando, quindi non importa quale immondizia lascia il primo ciclo al di fuori del byte basso di ciascun elemento dell'array.


Utilizza le istruzioni non documentatesalc per impostare AL da CF, nello stesso modo in cui lo sbb al,alfarebbe. È supportato su tutte le CPU Intel (tranne in modalità 64-bit), anche su Knight's Landing! La nebbia di Agner elenca i tempi per questo anche su tutte le CPU AMD (inclusa Ryzen), quindi se i produttori x86 insistono nel vincolare lo spazio di quel codice operativo fin dall'8086, potremmo anche approfittarne.

Trucchi interessanti:

  • trucco unsigned-compare per un isalpha () e un toupper () combinati e estende zero il byte per riempire eax, impostando per:
  • bitmap immediata in un registro per bt, ispirata a un output di compilatore perswitch .
  • Creazione di un array di dimensioni variabili nello stack con push in un ciclo. (Standard per asm, ma non qualcosa che puoi fare con C per la versione di stringa a lunghezza implicita). Utilizza 4 byte di spazio di stack per ogni carattere di input, ma consente di risparmiare almeno 1 byte rispetto al golf ottimale in circolazione stosb.
  • Invece di cmp / setne sull'array booleano, XOR booleana insieme per ottenere direttamente un valore di verità. ( cmp/ salcnon è un'opzione, perché salcfunziona solo per CF e 0xFF-0 non imposta CF. seteè 3 byte, ma eviterebbe incil ciclo esterno, per un costo netto di 2 byte (1 in modalità 64 bit )) vs. xor nel loop e risolvendolo con 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

Questa è probabilmente anche una delle risposte più veloci, dal momento che nessuno del golf fa davvero troppo male, almeno per stringhe con poche migliaia di caratteri in cui l'utilizzo della memoria 4x non causa molti errori di cache. (Potrebbe anche perdere le risposte che richiedono un inizio per stringhe non simili a Dennis prima di eseguire il loop su tutti i caratteri.) salcÈ più lento rispetto setcca molte CPU (ad esempio 3 uops contro 1 su Skylake), ma un controllo bitmap con bt/salcè ancora più veloce di una ricerca di stringhe o di una corrispondenza regex. E non c'è sovraccarico di avvio, quindi è estremamente economico per stringhe brevi.

Farlo in un passaggio al volo significherebbe ripetere il codice di classificazione per le direzioni su e giù. Sarebbe più veloce ma di dimensioni maggiori del codice. (Ovviamente se vuoi velocemente, puoi fare 16 o 32 caratteri alla volta con SSE2 o AVX2, usando ancora il trucco di confronto spostando il range verso il fondo del range firmato).


Programma di test (per Linux ia32 o x32) per chiamare questa funzione con un arg cmdline e uscire con status = valore di ritorno. strlenimplementazione da 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

È possibile utilizzare una versione a 64 bit di questa funzione sbb eax,eax, che è solo 2 byte anziché 3 per setc al. Avrebbe anche bisogno di un byte extra per deco notalla fine (perché solo 32 bit ha 1 byte inc / dec r32). Usando l'ABI x32 (puntatori a 32 bit in modalità lunga), possiamo ancora evitare i prefissi REX anche se copiamo e confrontiamo i puntatori.

setc [rdi]può scrivere direttamente in memoria, ma riservare byte ECX di spazio nello stack costa più dimensioni del codice rispetto a quelle salvate. (E dobbiamo spostarci attraverso l'array di output. [rdi+rcx]Richiede un byte in più per la modalità di indirizzamento, ma in realtà abbiamo bisogno di un contatore che non si aggiorni per i caratteri filtrati, quindi sarà peggio di così.)


Questa è la fonte YASM / NASM con %ifcondizionali. Può essere costruito con -felf32(codice a 32 bit) o -felfx32(codice a 64 bit con l'ABI x32) e con lunghezza implicita o esplicita . Ho testato tutte e 4 le versioni. Vedi questa risposta per uno script per creare un binario statico dalla sorgente NASM / YASM.

Per testare la versione a 64 bit su una macchina senza supporto per l'ABI x32, è possibile modificare i reg del puntatore a 64 bit. (Quindi sottrarre semplicemente il numero di prefissi REX.W = 1 (0x48 byte) dal conteggio. In questo caso, 4 istruzioni hanno bisogno dei prefissi REX per funzionare su reg a 64 bit). O semplicemente chiamalo con il rsppuntatore di input e nel basso 4G di spazio degli indirizzi.

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

Ho guardato in giro con DF (il flag di direzione che controlla lodsd/ scasde così via), ma non sembrava essere una vittoria. I soliti ABI richiedono che DF venga cancellato all'entrata e all'uscita della funzione. Supponendo che sia stato eliminato all'entrata, ma lasciarlo impostato all'uscita sarebbe un imbroglio, IMO. Sarebbe bello usare LODSD / SCASD per evitare i 3 byte sub esi, 4, specialmente nel caso in cui non ci siano rifiuti elevati.


Strategia bitmap alternativa (per stringhe di lunghezza implicita x86-64)

Si scopre che questo non salva alcun byte, perché bt r32,r32funziona ancora con immondizia elevata nell'indice di bit. Non è documentato così shrcom'è.

Invece di bt / sbbottenere il bit dentro / fuori da CF, usa uno shift / maschera per isolare il bit che vogliamo dalla bitmap.

%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

Dato che questo produce 0/1 in AL alla fine (invece di 0 / 0xFF), possiamo fare la necessaria inversione del valore di ritorno alla fine della funzione con xor al, 1(2B) invece di dec eax(anche 2B in x86-64) a produce ancora un valore di ritorno bool/_Bool corretto .

Questo ha usato per salvare 1B per x86-64 con stringhe di lunghezza implicita, evitando la necessità di azzerare i byte alti di EAX. (Stavo usando and eax, 0x7F ^ 0x20per forzare in maiuscolo e azzerare il resto di eax con un 3 byte and r32,imm8. Ma ora sto usando la codifica a 2 byte immediata con AL che la maggior parte delle istruzioni 8086 hanno, come già stavo facendo per il sube cmp.)

Si perde in bt/ salcnella modalità a 32 bit e le stringhe di lunghezza esplicita richiedono ECX per il conteggio, quindi non funziona neanche lì.

Ma poi ho capito che avevo torto: bt edx, eaxfunziona ancora con alta immondizia in eax. Apparentemente maschere il conteggio spostamento nello stesso modo shr r32, clfa (guardando solo basse 5 bit di cl). Questo è diverso dal bt [mem], regquale può accedere all'esterno della memoria a cui fa riferimento la modalità / dimensione di indirizzamento, trattandolo come una stringa di bit. (Crazy CISC ...)

Il manuale di riferimento insn set di Intel non documenta il mascheramento, quindi forse è il comportamento non documentato che Intel sta conservando per ora. (Questo genere di cose non è insolito. bsf dst, srcCon src = 0 lascia sempre dst non modificato, anche se è documentato che in questo caso dst abbia un valore indefinito. AMD documenta effettivamente il comportamento src = 0.) Ho provato su Skylake e Core2, e la btversione funziona con immondizia diversa da zero in EAX all'esterno di AL.

Un trucco pulito qui sta usando xchg eax,ecx(1 byte) per ottenere il conteggio in CL. Sfortunatamente, BMI2 shrx eax, edx, eaxè di 5 byte, contro solo 2 byte per shr eax, cl. L'utilizzo bextrrichiede un 2 byte mov ah,1(per il numero di bit da estrarre), quindi sono di nuovo 5 + 2 byte come SHRX + AND.


Il codice sorgente è diventato piuttosto disordinato dopo l'aggiunta di %ifcondizionali. Ecco lo smontaggio delle stringhe di lunghezza implicita x32 (usando la strategia alternativa per la bitmap, quindi è ancora 46 byte).

La differenza principale rispetto alla versione a lunghezza esplicita è nel primo ciclo. Notate come c'è un lodsprima, e in fondo, invece di uno solo all'inizio del ciclo.

    ; 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

Retina ,49 47 45 byte

\P{L}

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

Provalo online!

Salvato 2 byte grazie a Neil.

Salvati altri 2 byte grazie a Martin.

Rimuove le non lettere, quindi sostituisce le vocali con 1 e le consonanti con 2, per ottenere valori coerenti. Quindi rimuove ripetutamente il primo e l'ultimo carattere se sono uguali. Una volta che non lo sono, la parola era simmetrica se rimanevano uno o zero caratteri.


Funziona \D 2per farti risparmiare un paio di byte T`lL`2?
Neil,

@Neil Sì, sembra, bella cattura!
FryAmTheEggman,

Molto bene. Stavo cercando di fare questo :(
Christopher,

7

PHP, 82 byte

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

Provalo online!


È possibile anteporre il typecasting (bool)e rimuovere $s=il ==$ssegno di spunta e il segno di spunta per salvare 1 byte.
Kaiser

Se non sbaglio, potresti sostituire il (bool)con solo 0||per dire falso, o ... invece, salvando 3 byte aggiuntivi.
Kaiser

Hm. Non potresti usare \wper i caratteri di parole invece di a-z?
Kaiser

@kaiser \wcontiene cifre di sottolineatura e lettere. Questo non funzionerà ed [^/p{L}]è più lungo come [^a-z]più i. Confronto la stringa inversa con la stringa, quindi $sè necessaria per creare il valore booleano
Jörg Hülsermann

Questo è vero. Tuttavia gli altri dovrebbero funzionare. "Dovrebbe" ... lo fanno.
Kaiser

6

MATL, 14 byte

t3Y2m)13Y2mtP=

Provalo su MATL Online .

Ecco una versione leggermente modificata per verificare tutti i casi di test.

Spiegazione

        % 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

Lo dimostra con "Martin Ender" invece di "Dennis"? devo rivedere il titolo della sfida.
Roman Gräf,

1
Presumibilmente Suever voleva una dimostrazione che avesse una certa quantità di filtri al primo passo.
Greg Martin,

Quindi dovrebbe usare "Alex A." invece, ha anche un periodo.
Erik the Outgolfer

2
Sono confuso quale sia il problema. Ho scelto Martin Ender perché sarebbe effettivamente vero se si rimuovessero spazi e falso altrimenti. Ho anche incluso un link a tutti i casi di test
Suever,

6

Haskell, 84 75 74 69 byte

-10 grazie a @nimi
-5 grazie a @Zgarb

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

La comprensione dell'elenco sostituisce ogni lettera con un valore booleano e rimuove tutti gli altri caratteri. La prima parte controlla se l'elenco risultante è un palindromo.

Provalo online!


Due consigli: 1) Una comprensione dell'elenco è spesso abbreviata rispetto a quella filterseguita mapanche se si deve passare a non-poit-free. 2) Il <$>idè superfluo. f x=(==)<*>reverse$[elem c"aeiouAEIOU"|c<-x,celem ['A'..'Z']++['a'..'z']].
nimi,

È possibile rilasciare lo spazio tra ce "per un altro byte.
nimi,

1
Penso che c`elem`['A'..'Z']++['a'..'z']possa essere abbreviato in'@'<c,c<'{','`'<c||c<'['
Zgarb


4

Brachylog , 13 byte

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

Provalo online!

Spiegazione

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

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

Provalo online!

Uscite 1come truthy e niente come falsy.

Spiegazione

Ogni comando in questo programma viene eseguito in modalità ordinale, ma con una leggera rotazione nel modello che mi consente di salvare un byte. Se una newline è un valore di verità accettabile, posso salvare un altro byte con lo stesso metodo.

Linearizzato, il programma è il seguente:

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 byte

-1 byte grazie a @ovs

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

Provalo online!


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

3

JavaScript (ES6), 72 69 byte

Salvato 3 byte grazie a Neil

Restituisce un valore booleano.

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

Casi test


Salvare un paio di byte sostituendo le 2 stringhe vuote con 2.
Shaggy,

1
Ne hai bisogno +''alla fine? Ciò risparmierebbe invece 3 byte.
Neil,

Mi piace l'idea di @ Neil meglio!
Shaggy,

2

Mathematica, 113 byte

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

Puoi liberarti di alcuni byte:PalindromeQ@StringReplace[#,{Characters@"aeiouAEIOU"->"1",LetterCharacter->"0",_->""}]&
Non un albero

2

GolfScript , 42 byte

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

Provalo online!

La parte difficile sta generando l'alfabeto sia maiuscolo che minuscolo in una stringa, che useremo in una funzione di filtro per filtrare le lettere dall'input. Fortunatamente, poiché le stringhe in GolfScript sono solo matrici di punti di codice con una proprietà speciale, quindi possiamo semplicemente generare i punti di codice in modo efficiente. Ecco come li generiamo:

Innanzitutto, generiamo l'intervallo [0..122], 122 è il punto di codice per z. Quindi, prendiamo gli elementi dall'elemento dall'indice 65 in poi. 65 è il punto di codice per A. In questo momento, abbiamo [65..122]. Tutto bene, tranne che abbiamo alcuni punti di codice indesiderati ([91..96]). Quindi, per prima cosa facciamo un duplicato di quell'intervallo. Quindi, prendiamo gli elementi dall'indice 26 in poi e abbiamo [91..122]. Dopodiché, otteniamo gli elementi fino all'indice 5. incluso. Ora abbiamo [91..96]. Infine, rimuoviamo quegli elementi dal nostro [65..122], lasciandoci wil [65..90, 97..122]. Questi sono i punti di codice che vogliamo.

Ora che abbiamo creato l'elenco dei punti di codice dell'alfabeto superiore / inferiore, continuiamo la nostra funzione di filtro. La funzione viene mappata su ogni carattere della stringa di input, che, come ho detto inizialmente, viene invece analizzato come suo punto di codice. Quindi ora essenzialmente abbiamo [codepoint, [65..90, 97..122]]. Per scoprire se char codepointè una lettera, prendiamo semplicemente il suo indice nell'elenco che abbiamo creato. Se non è presente, verrà visualizzato -1come indice.

In questo momento, otteniamo un valore di falso solo se codepoint == 65, cioè il primo indice del nostro elenco, poiché solo allora l'indice sarebbe 0. Ma un singolo incremento risolverà questo problema e, ora, se codepointè nel nostro elenco, avremo ottiene il suo indice + 1, che è sempre un numero positivo, quindi sempre vero, mentre se non è lì otterremo -1 + 1 = 0, cioè falso.

Finalmente applichiamo la funzione che ho descritto ad ogni carattere dell'input e prendiamo solo i caratteri per i quali la funzione ha restituito un risultato veritiero.

Successivamente dobbiamo determinare se ogni carattere è una vocale o consonante. Poiché le vocali sono meno delle consonanti, la creazione di una stringa di vocali in modo che controlliamo che tale condizione sia più breve della creazione di una stringa di consonanti, quindi controlliamo se ogni carattere è una vocale. Ma, per verificare se l'elenco booleano è palindromico, abbiamo bisogno di booleani, che non otteniamo semplicemente prendendo l'indice + 1, poiché ciò può comportare un numero qualsiasi di [1..10] se il carattere è una vocale. E, come la maggior parte delle lingue del golf, anche questa non ha una boolfunzione. Quindi, usiamo semplicemente not not x, poiché notrestituisce sempre un valore booleano. Ma aspetta; abbiamo davvero bisogno di avere booleani specifici? Poiché notrestituisce sempre un valore booleano, perché non rimuoviamo semplicemente il secondonote effettivamente controlla se ogni carattere è una consonante? Sì, è esattamente quello che faremo!

Dopo il controllo, che restituisce un elenco di booleani, controlliamo se questo elenco booleano che abbiamo ottenuto è un palindromo, che è ciò che questa sfida ci chiede di fare. Bene, qual è la definizione di palindromo? Sì, un palindromo è un elenco o una stringa uguale al suo contrario. Quindi, come controlliamo? Semplice, lo dupliciamo, prendiamo il contrario e controlliamo contro l'elenco originale. Il risultato che otteniamo è, infine , ciò che il nostro codice dovrebbe restituire.


1
Spiegazione gigante per un programma a 42 byte. Ora immagino che sia piuttosto autoesplicativo ...
Erik the Outgolfer,

2

PHP , 87 byte

Versione PHP gratuita di Regex. Aggiunta una "vocale" poiché stripos può restituire 0 che è falso in PHP.

Difetto risolto da Jörg.

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

Provalo online!


Stesso numero di byte. for(;a&$c=$argn[$p++];)ctype_alpha($c)?$s.=stripos(_aeiou,$c)?0:1:0;echo$s==strrev($s);ma ottiene il risultato giusto per le stringhe che contengono zero
Jörg Hülsermann,

@ JörgHülsermann Grazie.
ME

2

q / kdb +, 42 38 byte

Soluzione:

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

Esempio:

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

Spiegazione:

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'

modifiche:

  • -4 byte; passare reverseper k equivalente|:

2

CJam , 26 byte

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

Provalo online!

-1 grazie a Esolanging Fruit .


È possibile sostituire 26,'af+con '{,97>per salvare un byte.
Esolanging Fruit,

@Esolanging: Assumi una risposta così vecchia ...
Erik the Outgolfer,

Un byte salvato sei mesi fa non è diverso da un byte salvato ora. Non è che ci sia l'inflazione in byte o altro: P
Esolanging Fruit

@EsolangingFruit Mi riferivo alla mia sempre crescente esperienza con il golf ... ovviamente hai ottenuto un credito come al solito, non ti preoccupare!
Erik the Outgolfer,

2

Braingolf,  4  3 byte

&JP

-1 byte grazie a Erik the Outgolfer

Ho scoperto che avevo Psempre avuto , anche prima di questa sfida.

J tuttavia, nonostante sia stato creato prima di questa sfida, non è stato spinto a github prima della sfida, quindi non è ancora in competizione.

Spiegazione:

&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

Perché avete bisogno n?
Erik the Outgolfer,

@EriktheOutgolfer perché sono un idiota certificato
Skidsdev

Hmm, hai dimenticato di rimuoverlo dalla spiegazione.
Erik the Outgolfer,

@EriktheOutgolfer Sono stato gunna a scrivere "Erick", quindi colpire la c, ma sembra proprio "Eriek"
Skidsdev,

Questo non fallirà per artisti del calibro di Alex A.?
Shaggy

1

Python 2, 83 byte

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

Definisce una funzione che dà TrueoFalse


È possibile salvare 2 byte utilizzando "aeiouAEIOU".__contains__invece di lambda y:y.lower()in"aeiou".
Blender,




1

Bash , 82 byte

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

Provalo online!

Riceve il nome come parametro, rimuove le non-lettere, sostituisce le vocali con 0, le non vocali né 0 con 1 e confronta con lo stesso invertito.

Potrebbe golf un po 'di più se riesci a lavorare con doppia o tripla sostituzione

Lo stato di uscita è 0 per vero e 1 per no.


Nelle recenti versioni bash, viene i=${i^^*};convertito iin maiuscolo. Ma penso che ti salvi solo un a-ze un aeiou, che è inferiore al 10B che costa.
Peter Cordes,

1

Japt v2.0a0, 19 11 byte

k\L mè\v ê¬

Provalo online


Spiegazione

        :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

Assioma, 126 byte

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

Pyke, 12 byte

#B)l1~-L{D_q

Provalo qui!

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

0

PowerShell, 87 byte

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

Ottieni una copia della stringa in cui le vocali sono 0 e le consonanti sono 1, con tutti i caratteri speciali rimossi, confronta quella stringa con una versione invertita unita a una stringa

Produzione:

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.