Trouvez les mots d'infini!

36

(Remarque: ceci est une retombée de mon précédent défi, Trouvez les mots tourbillonnants! )

Définition de mot Infinity :

  1. Si vous reliez par des courbes tous les caractères d'un mot Infinity de l'alphabet (AZ), vous obtenez le symbole de l'infini ∞, comme dans les schémas ci-dessous.
  2. Toutes les connexions paires doivent être en panne , toutes les connexions impaires doivent être en place .
  3. Vous pouvez ignorer les majuscules / minuscules ou considérer / convertir tout en majuscule ou tout en minuscule.
  4. Les mots entrés ne sont que des caractères dans la plage alphabétique de AZ, pas d'espaces, pas de ponctuation ni de symboles.
  5. Chaque mot doit comporter exactement 5 caractères. Les mots> 5 ou <5 ne sont pas valides.
  6. Si un mot a des caractères doubles consécutifs, le mot n'est pas valide, comme "FLOOD" ou "REINE".
  7. Tous les mots d'infini commencent et finissent avec le même caractère.

Voici quelques exemples:

Mots d'infini

Tâche:

Ecrivez un programme complet ou une fonction qui prendra un mot de l’entrée standard et qui sortira s’il s’agit d’un mot infini ou non. La sortie peut être vraie / fausse, 1/0, 1 / nulle, etc.

Cas de 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

Règles:

  1. Le code le plus court gagne.

Tâche facultative:

Trouvez, sous forme de liste, autant de mots Infinity que possible dans un dictionnaire anglais. Vous pouvez prendre par exemple comme référence la liste complète des mots anglais ici .

Mario
la source
Peut-on supposer que l'entrée est toujours de longueur 5? Vous avez défini la règle 5: " Chaque mot doit comporter exactement 5 caractères. Les mots> 5 ou <5 ne sont pas valides. ", Mais pas de mots PAS Infinity contenant moins de 5 caractères.
Kevin Cruijssen
4
C'est assez marrant que ALPHA crée ce motif
Fatalize
@KevinCruijssen Vous devez vérifier que le mot respecte la définition, j'ai mis à jour les faux cas.
Mario
1
@Arnauld cinq "A" se connectent à eux-mêmes (ou ne bougent pas du tout) en créant un seul point, il ne dessine pas le symbole de l'infini, donc je ne pense pas que ce soit un cas positif.
Mario
3
J'ai décidé de m'attaquer à la tâche facultative: "Trouvez sous forme de liste autant de mots Infinity que possible dans un dictionnaire anglais ..." J'ai utilisé cette source et la réponse de Kevin Cruijssen pour produire cette liste de 278 mots Infinity .
Thomas Quinn Kelly

Réponses:

19

Gelée , 43 41 40 25 24 23 22 21 14 13 octets

-7 octets grâce à fireflame241 ( 0ị=1ị$-> =ṚḢet utilisation de IIA⁼2,2pour tester les 4 rotations)

-1 Merci à Kevin Cruijssen (utilisation de nilad précédemment indisponible Ø2qui donne [2,2])

=ṚḢȧOIṠIIA⁼Ø2

TryItOnline
Ou tous les cas de test (plus "RULES")

Comment?

Un mot infini a:

  1. la même première et dernière lettre;
  2. longueur 5;
  3. pas de lettres égales les unes à côté des autres;
  4. somme de ses quatre deltas alphabétiques égale à zéro;
  5. somme de ses quatre signes delta de l'alphabet égale à zéro;
  6. deux deltas d'alphabet positifs ou deux deltas d'alphabets négatifs d'affilée.

Tous sauf (1) et (de manière équivalente) (4) peuvent être réduits à une condition selon laquelle les signes alphabétiques du triangle sont une rotation de [1,1,-1,-1](où le signe de 0est 0)

fireflame241 a noté que cela équivaut alors aux deltas des deltas des signes delta de l'alphabet dans [[2,2],[2,-2],[-2,2],[-2,-2]]lesquels on peut tester les valeurs absolues égales à [2,2]!

Comment?

=ṚḢȧ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)
Jonathan Allan
la source
Comment cela marche-t-il?
Oliver Ni
explication entrante.
Jonathan Allan
2
@PascalvKooten C'est principalement pour le plaisir et pour être compétitif au code golf - je suis un novice du code golf et de Jelly, donc assembler un programme Jelly est comme un petit casse-tête presque à chaque fois; Je trouve ça satisfaisant. Si vous souhaitez obtenir quelque chose de tangible dans ce jeu, vous devez l’utiliser pour perfectionner vos compétences dans une langue qui est plus communément utilisée dans le monde réel, ou bien, créer votre propre langue de golf!
Jonathan Allan
1
@ lois6b :). Vous commencez avec le tutoriel , puis utilisez les pages avec les définitions Atom , définitions Quicks , et parcourir le code source .
Jonathan Allan
1
14 octets Le golf principal utilise ici IIpour vérifier l’égalité avec une rotation de 1,1, -1, -1.
fireflame241
11

Java 8, 231 193 185 122 103 78 octets

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]

Essayez ici.

-38 octets merci à @ dpa97 de m'avoir rappelé d'utiliser char[]plutôt que String.
-63 octets grâce à la formule dérivée de @KarlNapf .
-25 octets en le convertissant de Java 7 à Java 8 (et renvoyant maintenant un booléen au lieu d'un entier).

193 octets répondent:

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;}

Explication:

  • Si la longueur de la chaîne n'est pas 5, on retourne false
  • Si le premier caractère ne correspond pas au dernier caractère, on retourne false
  • Ensuite, nous vérifions les quatre cas valides un par un (indiquons les cinq caractères de 1 à 5), et retournons trues’il est conforme à l’un d’eux (et falsesinon):
    1. Si les cinq personnages sont distribués comme: 1<2<3>4>5(ie ALPHA)
    2. Si les cinq caractères sont distribués comme: 1>2<3<4>5(c. -à EAGLE, HARSH, NINON, PINUP)
    3. Si les cinq personnages sont distribués comme: 1<2>3>4<5(ie RULER)
    4. Si les cinq personnages sont distribués comme: 1>2>3<4<5(ie THEFT, WIDOW)

Ces quatre règles peuvent être simplifiées 1*3<0 and 2*4<0(grâce à la réponse Python 2 de @KarlNapf ).

Kevin Cruijssen
la source
2
+1 pour compenser les votes non expliqués ... Pour autant que je sache, il s'agit d'une solution parfaitement fonctionnelle.
Arnauld
1
Je l'ai eu jusqu'à 215 convertir s en un caractère [] car [] c = s.toCharArray (); int z = c [1] -c [0], y = c [2] -c [1] ,. ..
dpa97
@ dpa97 Merci pour le rappel à utiliser char[]comme entrée à la place de String. -38 octets grâce à vous.
Kevin Cruijssen
1
Vos booléens peuvent être optimisés: z,xet w,ydoivent avoir un signe alternatif, il suffit donc de vérifier z*x<0etw*y<0
Karl Napf
@KarlNapf Ah, j'ai mal interprété votre commentaire il y a quelques heures. J'ai implémenté votre formule dérivée pour un énorme -63 octets. :) Merci.
Kevin Cruijssen
4

JavaScript (ES6), 91 89 87 octets

2 octets sauvés grâce à 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)

Comment ça marche

Nous construisons un masque binaire 4 bits kreprésentant les 4 transitions entre les 5 caractères de la chaîne:

k += p > c ? 1<<i : 0 / (p < c)
  • si le caractère précédent est supérieur au suivant, le bit est activé
  • si le caractère précédent est inférieur au suivant, le bit n'est pas activé
  • si le caractère précédent est identique au suivant, tout le masque binaire est forcé pour NaNque le mot soit rejeté (pour se conformer à la règle 6)

Les masques de bits valides sont ceux qui ont exactement deux 1transitions consécutives (le premier et le dernier bits étant également considérés comme consécutifs ):

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

En d'autres termes, ce sont les combinaisons qui sont:

  • k? : supérieur à 0
  • !(k%3): congru à 0 modulo 3
  • inférieur à 15

Les autres conditions sont:

  • !s[5] : il n'y a pas plus de 5 caractères
  • s[0]==s[4] : les 1er et 5ème caractères sont identiques

NB : Nous ne vérifions pas explicitement k != 15car tout mot suivant un tel motif sera rejeté par cette dernière condition.

Cas de test

Version initiale

Pour mémoire, ma version initiale était de 63 octets. Il réussit tous les tests mais ne détecte pas de caractères identiques consécutifs.

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

Voici une version de 53 octets suggérée par Neil dans les commentaires, qui fonctionne (et échoue) tout aussi bien:

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

Edit: Voir la réponse de Neil pour la version corrigée / complétée du code ci-dessus.

Arnauld
la source
0000est également congruent à 0 modulo 3 mais encore une fois, vous ne pouvez pas avoir les mêmes lettres, alors, comme 15, vous n'avez pas besoin de le tester explicitement.
Neil
Pouvez-vous utiliser pour cette version initiale !((a>b)-(b>c)+(c>d)-(d>e))?
Neil
p<c?0:NaNpeut être écrit en tant que 0/(p<c), ce qui enregistre 2 octets.
Ismael Miguel
@ Neil En ce qui concerne le test à 0: vous avez parfaitement raison. (Cependant, j'ai besoin du k?test à cause du possible NaN.) En ce qui concerne votre version alternative: cela devrait fonctionner.
Arnauld
@IsmaelMiguel - Bon appel! Merci.
Arnauld
4

JavaScript (ES6), 78 octets

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

Basé sur le code incorrect de @ Arnauld, mais joué au golf et corrigé. Fonctionne en vérifiant d’abord que le premier caractère est identique au cinquième (garantissant ainsi 5 caractères) et que la longueur de la chaîne n’excède pas 5. Après vérification des caractères en double consécutifs, il reste à vérifier l’ondulation de la chaîne, qui devrait avoir un pic et un creux deux lettres à part.

  • Si le sommet et le creux sont les lettres du milieu et les premières / dernières lettres, les deux premières comparaisons et les deux dernières comparaisons sont annulées.
  • Si le sommet et le creux sont les deuxième et quatrième lettres, les deux comparaisons du milieu et les deux comparaisons extérieures s'annulent
  • Sinon, quelque chose ne parvient pas à annuler et l'expression globale renvoie false

Edit: Solution alternative à 78 octets basée sur la réponse de @ 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
Neil
la source
3

Code de sortie Python 2, 56 octets

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

Sorties via le code de sortie: Erreur pour False et exécution réussie pour True.

Prend la chaîne savec des caractères abcde, la fait pivoter bcdea, effectue une comparaison élémentaire des caractères correspondants et les assigne à cinq variables v,w,x,y,z. La mauvaise longueur donne une erreur.

Les mots de l'infini ont tous

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

qui peut être vérifié conjointement comme v*x+w*y|z == -2 . La comparaison chaînée v*x+w*y|z>-2>_court-circuite si c'est le cas, et sinon continue à évaluer -2>_laquelle donne une erreur de nom.

Xnor
la source
Ah, c'est gentil de voir que vous avez plus joué au conditionnel!
Karl Napf
3

Python 2, 110 87 60 octets

Économiser 1 octet grâce à Neil

Nécessite une entrée entre guillemets, par exemple 'KNEES'

Trues'il s'agit d'un mot infini, Falsesi ce n'est pas le cas et qu'il a une longueur de 5 et affiche un message d'erreur si la longueur est incorrecte

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

Inspiré par la réponse de xnor en utilisantmap(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)

solution précédente:

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)

Utiliser la logique optimisée de Kevin Cruijssen

Karl Napf
la source
Pourquoi ne pas a*c+b*d+2==0==e?
Neil
@ Neil oui pourquoi pas, mais xnor a*c+b*d|eest encore plus court.
Karl Napf
Je pense que <-1pourrait fonctionner, puisque les deux -2|1et -2|-1égaux -1.
Neil
2

PHP, 102 octets

for(;$i<strlen($w=$argv[1]);)$s.=($w[$i++]<=>$w[$i])+1;echo preg_match("#^(2200|0022|2002|0220)#",$s);
Jörg Hülsermann
la source
2

Python 2, 71 octets

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

Prend la chaîne savec des caractères abcde, la fait pivoter bcdeaet effectue une comparaison élémentaire des caractères correspondants.

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)

Le résultat est une liste de -1, 0, 1. Ensuite, vérifie si le résultat est l’une des séquences valides de hauts et de bas:

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

tel que généré à partir du modèle [m,n,-m,-n,0]avec m,n=±1. La dernière 0vérifie que la première et la dernière lettre sont égales, et la longueur garantit que la chaîne d'entrée a une longueur de 5.


Une alternative 71. Vérifie les conditions relatives aux comparaisons tout en garantissant la bonne longueur.

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
Xnor
la source
1

R, 144 octets

La réponse est basée sur la logique de Jonathan Allan. Cela pourrait probablement être joué au golf.

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)

Cas de test R-fiddle (exemple vectorisé mais même logique)

Billywob
la source
Puisque vous avez déjà un chèque length(s)==5, vous pouvez le remplacer s[1]==tail(s,1)par s[1]==s[5]. Une méthode plus courte d'un octet pour vérifier la longueur est is.na(s[6]). Ensemble, ces deux modifications retournent TRUEpour une slongueur de 5 exactement et FALSEsinon, tel TRUE&NAquel NAmais FALSE&NAest FALSE. Vous pouvez également sauvegarder quelques octets en remplaçant !sum(sign(d))&any(rle(sign(d))$l>1)par !sum(a<-sign(d))&any(rle(a)$l>1).
rturnbull
1

GNU Prolog, 47 octets

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

Définit un prédicati qui réussit (un nombre infini de fois, en fait) pour un mot infini, produisant ainsi "oui" lorsqu'il est exécuté depuis l'interpréteur (comme d'habitude pour Prolog); échoue pour un mot candidat dont les première et dernière lettres ne correspondent pas ou ne compte pas 5 lettres, générant ainsi «non» lorsqu'il est exécuté à partir de l'interprète; et se bloque avec un débordement de pile si on donne un mot candidat qui n'est pas un mot infini, mais qui est composé de cinq lettres avec les deux premières et dernières correspondantes. (Je ne suis pas sûr pourquoiil se bloque; l'appel récursif doit pouvoir être traité comme un appel d'urgence. Apparemment, l'optimiseur de GNU Prolog n'est pas très bon.) Réussir équivaut à la vérité de Prolog, et échouer à l'équivalent de Falsey; un crash est définitivement plus un falsey que une vérité, et le corriger allongerait considérablement la solution, aussi, j’espère que cela compte comme une solution valable.

L'algorithme est assez simple (et en effet, le programme est assez lisible); vérifiez si les lettres forment l'un des quatre motifs formant un mot infini, sinon, permutez-les cycliquement et réessayez. Nous n'avons pas besoin de vérifier explicitement les doubles lettres, car les opérateurs <and >nous laissent implicitement vérifier cela en même temps que nous vérifions la correspondance des deltas.


la source
1

En fait , 38 27 octets

Cette réponse a été largement inspirée par l'excellente réponse de Jonathan Allan sur Jelly . Il y a probablement plusieurs endroits où cela peut être joué au golf, alors vos suggestions sont les bienvenues! Essayez-le en ligne!

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.
Sherlock9
la source
1

TI-BASIC, 81 octets

La chaîne à passer dans le programme est en Ans. Retourne (et affiche implicitement) 1 si le mot entré est un mot infini et 0 (ou quitte avec un message d'erreur) s'il ne l'est pas.

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

Erreurs sur des caractères répétés ou des mots autres que 5 lettres.

Josiah Winslow
la source
1

05AB1E , 16 octets

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

Port de @JonathanAllan réponse gelée de .

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

Ç             # 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)
Kevin Cruijssen
la source