Trova le parole dell'infinito!


36

(Nota: questo è uno spin-off della mia precedente sfida Trova le parole vorticose! )

Definizione di Infinity Word :

  1. Se colleghi con le curve tutti i caratteri di una Parola infinita sull'alfabeto (AZ) otterrai il simbolo dell'infinito ∞ come negli schemi sotto.
  2. Tutte le connessioni pari devono essere inattive , tutte le connessioni dispari devono essere attive .
  3. È possibile ignorare le maiuscole / minuscole o considerare / convertire tutto in maiuscolo o tutto in minuscolo.
  4. Le parole di input sono solo caratteri nell'intervallo alfabetico di AZ, nessuno spazio, nessuna punteggiatura o simboli.
  5. Ogni parola deve contenere esattamente 5 caratteri. Le parole> 5 o <5 non sono valide.
  6. Se una parola ha due caratteri consecutivi, la parola non è valida, come "INONDAZIONE" o "REGINA".
  7. Tutte le Infinity Words iniziano e finiscono con lo stesso personaggio.

Ecco alcuni esempi:

Infinity Words

Compito:

Scrivi un programma o una funzione completa che prenderà una parola dall'input standard e verrà emesso se è una parola infinita o meno. L'output può essere true / false, 1/0, 1 / Null, ecc.

Casi test:

Infinity Words:
ALPHA, EAGLE, HARSH, NINON, PINUP, RULER, THEFT, WIDOW

NOT Infinity Words:
CUBIC, ERASE, FLUFF, LABEL, MODEM, RADAR, RIVER, SWISS, TRUST, 
KNEES, QUEEN, GROOVE, ONLY, CHARACTER, OFF, IT, ORTHO

Regole:

  1. Il codice più corto vince.

Attività opzionale:

Trova, come elenco, quante più parole Infinity che puoi in un dizionario inglese. Puoi prendere ad esempio come riferimento l'elenco completo di parole inglesi qui .


Possiamo supporre che l'ingresso sia sempre di lunghezza 5? Hai definito la regola 5: " Ogni parola deve contenere esattamente 5 caratteri. Le parole> 5 o <5 non sono valide. ", Ma NON le parole di infinito contenenti meno o più di 5 caratteri.
Kevin Cruijssen,

4
Abbastanza divertente che ALPHA
crei

@KevinCruijssen Devi verificare che la parola rispetti la definizione, ho aggiornato i casi falsi.
Mario,

1
@Arnauld cinque "A" si collegano a se stessi (o non si muovono affatto) creando un singolo punto, non disegna il simbolo dell'infinito, quindi non penso che sia un caso positivo.
Mario,

3
Ho deciso di affrontare il compito opzionale: "Trova, come elenco, quante più parole Infinity che puoi in un dizionario inglese ..." Ho usato questa fonte e la risposta di Kevin Cruijssen , per produrre questo elenco di 278 parole Infinity .
Thomas Quinn Kelly,

Risposte:


19

Gelatina , 43 41 40 25 24 23 22 21 14 13 byte

-7 byte grazie a fireflame241 ( 0ị=1ị$-> =ṚḢe utilizzo di IIA⁼2,2per testare le 4 rotazioni)

-1 Grazie a Kevin Cruijssen (uso di nilad precedentemente non disponibile Ø2che produce [2,2])

=ṚḢȧOIṠIIA⁼Ø2

TryItOnline
O tutti i casi di test (più "REGOLE")

Come?

Una parola infinita ha:

  1. la stessa prima e ultima lettera;
  2. lunghezza 5;
  3. nessuna lettera uguale l'una accanto all'altra;
  4. somma dei suoi quattro delta alfabetici pari a zero;
  5. somma dei suoi quattro segni delta alfabetici pari a zero;
  6. due delta alfabetici positivi o due delta alfabetici negativi di fila.

Tutti tranne (1) e (equivalentemente) (4) possono essere ridotti a condizione che i segni delta dell'alfabeto siano una rotazione di [1,1,-1,-1](dove il segno di 0è0 )

fireflame241 ha osservato che questo equivale quindi ai delta dei delta dei segni di delta alfabetici in [[2,2],[2,-2],[-2,2],[-2,-2]]cui possono essere verificati i valori assoluti uguali [2,2]!

Come?

=ṚḢȧOIṠIIA⁼Ø2 - Main link: word
 Ṛ            - reverse word
=             - equals? (vectorises)
  Ḣ           - head (is the first character equal to the last?)
   ȧ          - and
    O         - cast word to ordinals
     I        - increments - the alphabet deltas (or just [] if 1st != last)
      Ṡ       - sign (vectorises)
       I      - increments - deltas of those signs
        I     - increments - deltas of those
         A    - absolute value (vectorises)
           Ø2 - literal [2,2]
          ⁼   - equals? (non-vectorising version)

Come funziona?
Oliver Ni,

spiegazione in arrivo.
Jonathan Allan,

2
@PascalvKooten È principalmente per divertimento ed essere competitivo nel code golf - Sono abbastanza nuovo sia per il code golf che per la Jelly, quindi mettere insieme un programma Jelly è come un piccolo puzzle quasi ogni volta; Lo trovo soddisfacente. Se si desidera ottenere qualcosa di tangibile da questo gioco, è necessario utilizzarlo per affinare le proprie abilità in un linguaggio che è più comunemente usato nel mondo reale, o, naturalmente, per creare un linguaggio da golf per conto proprio!
Jonathan Allan,

1
@ lois6b :). Si inizia con il tutorial , quindi si utilizzano le pagine con definizioni Atom , definizioni Quicks e si sfoglia il codice sorgente .
Jonathan Allan,

1
14 byte Il golf principale qui utilizza IIper verificare l'uguaglianza con una rotazione di 1,1, -1, -1.
fireflame241

11

Java 8, 231 193 185 122 103 78 byte

s->s.length==5&&(s[1]-s[0])*(s[3]-s[2])<0&(s[2]-s[1])*(s[4]-s[3])<0&s[4]==s[0]

Provalo qui.

-38 byte grazie a @ dpa97 per avermi ricordato di usare al char[]posto di String.
-63 byte grazie alla formula derivata di @KarlNapf .
-25 byte convertendolo da Java 7 a Java 8 (e ora restituendo un valore booleano anziché intero).

193 byte rispondono:

int c(char[]s){if(s.length!=5)return 0;int a=s[0],b=s[1],c=s[2],d=s[3],e=s[4],z=b-a,y=c-b,x=d-c,w=e-d;return e!=a?0:(z>0&y>0&x<0&w<0)|(z<0&y>0&x>0&w<0)|(z>0&y<0&x<0&w>0)|(z<0&y<0&x>0&w>0)?1:0;}

Spiegazione:

  • Se la lunghezza della stringa non è 5, torniamo false
  • Se il primo personaggio non è uguale all'ultimo, torniamo false
  • Quindi controlliamo i quattro casi validi uno per uno (indichiamo i cinque caratteri come da 1 a 5), ​​e ritorniamo truese è conforme a uno di essi (e falsealtrimenti):
    1. Se i cinque caratteri sono distribuiti come: 1<2<3>4>5(es. ALPHA)
    2. Se i cinque caratteri sono distribuiti come: 1>2<3<4>5(vale a dire EAGLE, HARSH, NINON,PINUP )
    3. Se i cinque caratteri sono distribuiti come: 1<2>3>4<5(es. RULER)
    4. Se i cinque caratteri sono distribuiti come: 1>2>3<4<5(cioè THEFT, WIDOW)

Queste quattro regole possono essere semplificate 1*3<0 and 2*4<0(grazie alla risposta Python 2 di @KarlNapf ).


2
+1 per compensare il downvote inspiegabile ... Per quanto posso dire, questa è una soluzione perfettamente funzionale.
Arnauld,

1
Sono arrivato a 215 convertendo s in un char [] char [] c = s.toCharArray (); int z = c [1] -c [0], y = c [2] -c [1] ,. ..
dpa97,

@ dpa97 Grazie per il promemoria da utilizzare char[]come input anziché String. -38 byte grazie a te.
Kevin Cruijssen,

1
I tuoi booleani possono essere ottimizzati: z,xe w,ydevono avere un segno alternato, quindi è sufficiente controllare z*x<0ew*y<0
Karl Napf,

@KarlNapf Ah, ho frainteso il tuo commento qualche ora fa. Ho implementato la tua formula derivata per un enorme -63 byte. :) Grazie.
Kevin Cruijssen,

4

JavaScript (ES6), 91 89 87 byte

Salvato 2 byte grazie a Ismael Miguel

s=>(k=0,[...s].reduce((p,c,i)=>(k+=p>c?1<<i:0/(p<c),c)),k?!(k%3)&&!s[5]&&s[0]==s[4]:!1)

Come funziona

Costruiamo una maschera di bit a 4 bit che krappresenta le 4 transizioni tra i 5 caratteri della stringa:

k += p > c ? 1<<i : 0 / (p < c)
  • se il carattere precedente è più alto di quello successivo, viene impostato il bit
  • se il carattere precedente è inferiore a quello successivo, il bit non è impostato
  • se il carattere precedente è identico al successivo, l'intera maschera di bit viene forzata in NaNmodo che la parola venga respinta (per rispettare la regola 6)

Le maschere di bit valide sono quelle che hanno esattamente due 1transizioni consecutive (anche il primo e l'ultimo bit sono considerati consecutivi ):

Binary | Decimal
-------+--------
0011   | 3
0110   | 6
1100   | 12
1001   | 9

In altre parole, queste sono le combinazioni che sono:

  • k? : maggiore di 0
  • !(k%3): congruente a 0 modulo 3
  • inferiore a 15

Le altre condizioni sono:

  • !s[5] : non ci sono più di 5 caratteri
  • s[0]==s[4] : il 1o e il 5o personaggio sono identici

NB : Non controlliamo esplicitamente k != 15perché qualsiasi parola che segue tale schema verrà rifiutata da quest'ultima condizione.

Casi test

Versione iniziale

Per la cronaca, la mia versione iniziale era di 63 byte. Sta superando con successo tutti i casi di test ma non riesce a rilevare caratteri identici consecutivi.

([a,b,c,d,e,f])=>!f&&a==e&&!(((a>b)+2*(b>c)+4*(c>d)+8*(d>e))%3)

Di seguito una versione di 53 byte suggerita da Neil nei commenti, che funziona (e fallisce) ugualmente bene:

([a,b,c,d,e,f])=>!f&&a==e&&!((a>b)-(b>c)+(c>d)-(d>e))

Modifica: vedi la risposta di Neil per la versione fissa / completata del codice sopra.


0000è anche congruente con 0 modulo 3 ma di nuovo non è possibile avere la prima e l'ultima lettera uguali, quindi, come 15, non è necessario verificarlo esplicitamente.
Neil,

Per quella versione iniziale, puoi usare !((a>b)-(b>c)+(c>d)-(d>e))?
Neil,

p<c?0:NaNpuò essere scritto come 0/(p<c), il che consente di risparmiare 2 byte.
Ismael Miguel,

@Neil Per quanto riguarda il test contro 0: hai perfettamente ragione. (Tuttavia, ho bisogno del k?test a causa del possibile NaN.) Per quanto riguarda la tua versione alternativa: dovrebbe funzionare davvero.
Arnauld,

@IsmaelMiguel - Buona chiamata! Grazie.
Arnauld,

4

JavaScript (ES6), 78 byte

([a,b,c,d,e,f])=>a==e&&!(f||/(.)\1/.test(a+b+c+d+e)||(a>b)-(b>c)+(c>d)-(d>e))

Basato sul codice errato di @ Arnauld, ma giocato a golf e corretto. Funziona verificando innanzitutto che il primo carattere sia uguale al quinto (garantendo così 5 caratteri) e che la lunghezza della stringa non sia superiore a 5. Dopo aver verificato la presenza di caratteri duplicati consecutivi, rimane da controllare l'ondulazione della stringa, che dovrebbe avere un picco e un trogolo a due lettere di distanza.

  • Se il picco e il trogolo sono la metà e la prima / ultima lettera, i primi due confronti e gli ultimi due confronti si annullano
  • Se il picco e il trogolo sono la seconda e la quarta lettera, i due confronti centrali e i due confronti esterni si annullano
  • Altrimenti, qualcosa non riesce ad annullare e l'espressione generale restituisce false

Modifica: soluzione alternativa a 78 byte basata sulla risposta di @ KarlNapf:

([a,b,c,d,e,f],g=(a,b)=>(a<b)-(a>b))=>a==e&&!f&&g(a,b)*g(c,d)+g(b,c)*g(d,e)<-1

3

Codice di uscita Python 2, 56 byte

s=input()
v,w,x,y,z=map(cmp,s,s[1:]+s[0])
v*x+w*y|z>-2>_

Output tramite codice di uscita: errore per False e esecuzione corretta per True.

Prende la stringa scon caratteri abcde, la ruota in bcdea, esegue un confronto elementalmente dei caratteri corrispondenti e li assegna a cinque variabili v,w,x,y,z. La lunghezza errata genera un errore.

Le parole dell'infinito tutte hanno

v*x == -1
w*y == -1
z == 0

che può essere verificato congiuntamente come v*x+w*y|z == -2. Il confronto incatenato mette in v*x+w*y|z>-2>_corto circuito se questo è il caso, e continua a valutare -2>_quale dà un errore di nome.


Ah, è bello come hai golfato il condizionale di più!
Karl Napf,

3

Python 2, 110 87 60 byte

Risparmio di 1 byte grazie a Neil

Richiede input racchiuso tra virgolette, ad es 'KNEES'

Truese è una parola infinita, in Falsecaso contrario e ha una lunghezza di 5 e stampa un messaggio di errore in caso di lunghezza errata

s=input()
a,b,c,d,e=map(cmp,s,s[1:]+s[0])
print a*c+b*d|e<-1

Ispirato dalla risposta di xnor utilizzandomap(cmp...

s=input()
e=map(cmp,s,s[1:]+s[0])
print e[4]==0and e[0]*e[2]+e[1]*e[3]==-2and 5==len(s)

soluzione precedente:

s=input()
d=[ord(x)-ord(y)for x,y in zip(s,s[1:])]
print s[0]==s[4]and d[0]*d[2]<0and d[1]*d[3]<0and 4==len(d)

Utilizzando la logica ottimizzata di Kevin Cruijssen


Perché no a*c+b*d+2==0==e?
Neil,

@Neil sì, perché no, ma xnor's a*c+b*d|eè ancora più breve.
Karl Napf,

Credo che <-1il lavoro potrebbe, dal momento che entrambi -2|1e -2|-1uguali -1.
Neil,

2

PHP, 102 byte

for(;$i<strlen($w=$argv[1]);)$s.=($w[$i++]<=>$w[$i])+1;echo preg_match("#^(2200|0022|2002|0220)#",$s);

2

Python 2, 71 byte

lambda s:map(cmp,s,s[1:]+s[0])in[[m,n,-m,-n,0]for m in-1,1for n in-1,1]

Prende la stringa scon caratteri abcde, la ruota su bcdeae fa un confronto elementally dei caratteri corrispondenti.

a  b   cmp(a,b)
b  c   cmp(b,c)
c  d   cmp(c,d)
d  e   cmp(d,e)
e  a   cmp(e,a)

Il risultato è un elenco di -1, 0, 1. Quindi, controlla se il risultato è una delle sequenze valide di su e giù:

[-1, -1, 1, 1, 0]
[-1, 1, 1, -1, 0]
[1, -1, -1, 1, 0]
[1, 1, -1, -1, 0]

come generato dal modello [m,n,-m,-n,0]con m,n=±1. L'ultima 0verifica che la prima e l'ultima lettera fossero uguali e la lunghezza assicura che la stringa di input avesse lunghezza 5.


Un'alternativa 71. Verifica le condizioni sui confronti garantendo la giusta lunghezza.

def f(s):a,b,c,d,e=map(cmp,s,s[1:]+s*9)[:5];print a*c<0==e>b*d>len(s)-7

1

R, 144 byte

La risposta si basa sulla logica di @Jonathan Allan. Probabilmente potrebbe essere giocato a golf però.

s=strsplit(scan(,""),"")[[1]];d=diff(match(s,LETTERS));s[1]==tail(s,1)&length(s)==5&all(!rle(s)$l-1)&!sum(d)&!sum(sign(d))&any(rle(sign(d))$l>1)

Casi di test R-fiddle (esempio vettorizzato ma stessa logica)


Dal momento che hai già un controllo che length(s)==5, è possibile sostituire s[1]==tail(s,1)con s[1]==s[5]. Un metodo più breve di un byte per verificare la lunghezza è is.na(s[6]). Insieme, questi due cambiamenti ritornano TRUEper la slunghezza 5 esattamente e FALSEaltrimenti, come TRUE&NAè NAma FALSE&NAè FALSE. È inoltre possibile salvare alcuni byte sostituendoli !sum(sign(d))&any(rle(sign(d))$l>1)con !sum(a<-sign(d))&any(rle(a)$l>1).
rturnbull,

1

GNU Prolog, 47 byte

i([A,B,C,D,A]):-A>B,B>C,C<D,D<A;i([B,C,D,A,B]).

Definisce un predicato iche riesce (infinitamente molte volte, in effetti) per una parola infinita, emettendo così "sì" quando eseguito dall'interprete (come al solito per Prolog); non riesce per una parola candidata la cui prima e ultima lettera non corrispondono, o non è lunga 5 lettere, quindi emette "no" quando viene eseguita dall'interprete; e va in crash con un overflow dello stack se viene data una parola candidata che non è una parola infinita, ma che è di cinque lettere con la prima e le ultime due corrispondenze. (Non sono sicuro del perché si arresta in modo anomalo; la chiamata ricorsiva dovrebbe essere curabile come una chiamata di coda. Apparentemente l'ottimizzatore di GNU Prolog non è molto buono.) Riuscire è l'equivalente di verità di Prolog e fallire l'equivalente di falsità; un incidente è sicuramente più falso che vero, e risolverlo renderebbe la soluzione sostanzialmente più lunga, quindi spero che questo valga come una soluzione valida.

L'algoritmo è abbastanza semplice (e in effetti il ​​programma è abbastanza leggibile); controlla se le lettere formano uno dei quattro schemi che formano una parola infinita e, in caso contrario, lo consentono ciclicamente e riprova. Non abbiamo bisogno di esplicitamente verificare la presenza di lettere doppie come <e >operatori fateci implicitamente controllare che allo stesso tempo che controlliamo che i delta corrispondono.


1

In realtà , 38 27 byte

Questa risposta è stata in gran parte ispirata dall'eccellente risposta Jelly di Jonathan Allan . Probabilmente ci sono molti posti in cui questo può essere giocato a golf, quindi i suggerimenti sul golf sono i benvenuti! Provalo online!

O;\♀-dY@♂s4R`0~;11({k`Míub*

Ungolfing

     Implicit input s.
O    Push the ordinals of s. Call this ords.
;    Duplicate ords.
\    Rotate one duplicate of ords left by 1.
♀-   Vectorized subtraction. This effectively gets the first differences of ords.
d    Pop ord_diff[-1] onto the stack. This is ords[0] - ords[-1].
Y    Logical negate ord_diff[-1], which returns 1 if s[0] == s[-1], else 0.
@    Swap (s[0] == s[-1]) with the rest of ord_diff.

♂s       Vectorized sgn() of ord_diff. This gets the signs of the first differences.
4R       Push the range [1..4] onto the stack.
`...`M   Map the following function over the range [1..4]. Variable x.
  0~;      Push -1 onto the stack twice.
  11       Push 1 onto the stack twice.
  (        Rotate x to TOS.
  {        Rotate the stack x times, effectively rotating the list [1, 1, -1, -1].
  k        Wrap it all up in a list.

     Stack: list of rotations of [1, 1, -1, -1], sgn(*ord_diff)
í    Get the 0-based index of sgn(*ord_diff) from the list of rotations. -1 if not found.
ub   This returns 1 only if sgn(*ord_diff) was found, else 0.
     This checks if the word loops like an infinity word.

*    Multiply the result of checking if the word s loops and the result of s[0] == s[-1].
     Implicit return.


1

TI-BASIC, 81 byte

La stringa da passare al programma è in Ans. Restituisce (e visualizza implicitamente) 1 se la parola inserita è una parola infinita e 0 (o esce con un messaggio di errore) se non lo è.

seq(inString("ABCDEFGHIJKLMNOPQRSTUVWXYZ",sub(Ans,A,1)),A,1,length(Ans
min(Ans(1)=Ans(5) and {2,2}=abs(deltaList(deltaList(deltaList(Ans)/abs(deltaList(Ans

Errori su eventuali caratteri ripetuti o parole non di 5 lettere.


1

05AB1E , 16 byte

Ç¥DO_s.±¥¥Ä2DиQ*

Porto di @JonathanAllan risposta di Jelly al .

Provalo online o verifica tutti i casi di test .

Spiegazione:

Ç             # Convert the (implicit) input string to a list of unicode values
              #  i.e. "RULES" → [82,85,76,69,82]
 ¥            # Take the deltas
              #  i.e. [82,85,76,69,82] → [3,-9,-7,13]
  DO          # Duplicate and take the sum
              #  i.e. [3,-9,-7,13] → 0
    _         # Check if that sum is exactly 0
              # (which means the first and last characters are equal)
              #  i.e. 0 and 0 → 1 (truthy)
 s            # Swap so the deltas are at the top of the stack again
            # Get the sign of each
              #  i.e. [3,-9,-7,13] → [1,-1,-1,1]
    ¥         # Get the deltas of those signs
              #  i.e. [1,-1,-1,1] → [-2,0,2]
     ¥        # And then get the deltas of those
              #  i.e. [-2,0,2] → [2,2]
      Ä       # Convert them to their absolute values
       2Dи    # Repeat the 2 two times as list: [2,2]
          Q   # Check if they are equal
              #  i.e. [2,2] and [2,2] → 1 (truthy)
 *            # Check if both are truthy (and output implicitly)
              #  i.e. 1 and 1 → 1 (truthy)
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.