Vérificateur d'isogrammes

13

Défi :

Étant donné un mot, vérifiez s'il s'agit ou non d'un isogramme.


Quelle :

Un isogramme est un mot composé uniquement de lettres sans doublons (insensible à la casse). La chaîne vide est un isogramme.


Exemples :

"Dermatoglyphics"     ---> true
"ab"                  ---> true
"aba"                 ---> false
"moOse"               ---> false
"abc1"                ---> false
""                    ---> true

Contribution :

Vous pouvez accepter une entrée dans n'importe quel format raisonnable

L'entrée ne contiendra que des lettres et / ou des chiffres, pas d'espaces ( [a-zA-Z0-9])


Production :

  • true ou toute valeur vraie si l'entrée est un isogramme
  • false ou toute valeur de fausse autrement

C'est le donc le code le plus court en octets dans chaque langue gagne.

Muhammad Salman
la source
3
Cas de test suggéré:sad2
Adám
1
Votre définition de l'isogramme comprend deux déclarations contradictoires différentes. Lequel est-ce?
Post Rock Garf Hunter
9
Je vous recommande de commencer à utiliser le bac à sable afin que ces problèmes puissent être détectés avant de publier le défi.
fəˈnɛtɪk
3
@MuhammadSalman C'est très bâclé, veuillez supprimer ". N'importe" à la fin de votre citation et donner quelques exemples supplémentaires ( sad2daséchouerait même sans le 2donc il n'affiche rien).
Asone Tuhid
4
Le "Quoi" et les "Notes" semblent se contredire: "Mettre en œuvre une fonction qui détermine si une chaîne qui ne contient que des lettres est un isogramme" (soulignement ajouté) et "Il peut y avoir des chiffres et ceux-ci doivent et doivent retourner faux" dire des choses opposées. J'ai voté pour la fermeture car pas clair pour le moment, mais je serai ravi de le retirer une fois que tout sera éclairci!
Giuseppe

Réponses:

9

Python deux / 3, 36 52 48 octets

lambda s:len(s)==len({*s.lower()}-{*str(56**7)})

Essayez-le en ligne!

Je profite du fait qu'il setne contient que des éléments uniques. En invoquant la __len__méthode de chacun, je peux déterminer si scontient également uniquement des éléments uniques (en ignorant la casse).

EDIT: mis à jour pour satisfaire l'exigence précédemment ignorée de renvoyer False pour les entrées numériques. L'ensemble de tous les chiffres est codé comme set(str(56**7)).

EDIT 2: Suite à cette suggestion d'utilisateur , je profite maintenant du déballage des arguments pour définir la compréhension. Cela rompt formellement la compatibilité avec Python 2.

Scott Norton
la source
3
bienvenue chez PPCG! Ceci est également censé retourner falselorsqu'il scontient un caractère numérique.
Giuseppe
utilise `56**7`(comme dans l'autre réponse python) au lieu de str()plus court? Je ne connais pas le python mais cela semble être la principale différence entre vos deux réponses.
Giuseppe
@Giuseppe python3 n'en a pas ``, une version python2 uniquement permettrait d'économiser 4 octets (3 sur ce + 1 sur division au lieu de cela équivaut)
Rod
@Rod exactement à droite. Curieusement, le a 56**7été inspiré par votre propre encodage des chiffres 0-9 ci-dessous, mais vous permet d'économiser sur le vôtre d'un octet.
Scott Norton
Peut-être pouvez-vous ajouter une version Python 2? 46 octets:lambda s:len(s)==len(set(s.lower())-{`56**7`})
Sunny Patel
5

05AB1E , 5 octets

lDáÙQ

Essayez-le en ligne!

Explication

l        # convert input to lower-case
 D       # duplicate
  á      # keep only letters
   Ù      # remove duplicates
    Q     # compare for equality
Emigna
la source
4

R , 41 octets

!grepl("(.).*\\1|\\d",tolower(scan(,"")))

Essayez-le en ligne!

Approche regex. !grepl(regex,scan(,""),F)n'a pas fonctionné, donc je suppose que la capture ne correspond pas à la casse dans R? Je suis mauvais en regex en général, cependant, je ne serai donc pas surpris si je fais juste mal ...

R , 58 octets

!anyDuplicated(c(el(strsplit(tolower(scan(,"")),"")),0:9))

Essayez-le en ligne!

Ajoute les chiffres 0:9à la liste (en minuscules) de caractères et teste s'il y a des doublons.

Giuseppe
la source
3

Rubis , 25 23 21 octets

-2 octets sur les deux grâce à Giuseppe

->s{/(.).*\1|\d/i!~s}

Essayez-le en ligne!


-2 octets grâce à Kirill L.

Rubis -n , 21 19 18 16 octets

p !/(.).*\1|\d/i

Essayez-le en ligne!

Asone Tuhid
la source
@Giuseppe Je ne pensais pas que cela fonctionnerait, merci
Asone Tuhid
1
Je pense que, dans la deuxième version, vous n'avez même pas besoin $_- il suffit de lancer une expression régulière sans rien d'autre qui le compare implicitement à $_: 16 octets
Kirill L.
@KirillL. merci, je ne l'ai jamais vu !/.../auparavant , je ne le trouve même pas sur ruby-doc.org
Asone Tuhid
Pas étonnant, j'en ai aussi entendu parler ici après avoir demandé conseil à un gars de Perl :)
Kirill L.
@KirillL. pas étonnant non plus, l'étrangeté rubis est généralement héritée de perl
Asone Tuhid
3

Brachylog , 4 octets

ḷo⊆Ạ

Essayez-le en ligne!

Le prédicat réussira si l'entrée est un isogramme et échouera dans le cas contraire, produisant l'alphabet latin en minuscules s'il réussit. Étant donné que le prédicat intégré de Brachylog ne correspond pas exactement à la relation ordinaire entre un sous-ensemble et un sur-ensemble, j'ai dû dépenser un octet pour trier l'entrée en minuscules, mais j'ai économisé un octet pour ne pas avoir à vérifier explicitement les doublons. (Si cela n'avait pas besoin d'échouer avec les chiffres, nous pourrions simplement l'utiliser ḷ≠.)

Chaîne indépendante
la source
2

Husk , 6 octets

§=f√ü_

Essayez-le en ligne!

Explication

§=f√ü_  -- takes a string as argument, eg: "sAad2"
§       -- fork the argument..
  f√    -- | filter out non-letters: "sad"
    ü_  -- | deduplicate by lower-case: "sAd2"
 =      -- ..and compare: 0
ბიმო
la source
2

Japt , 12 octets

;v
oC ‰ eUq

Explication:

;v
;         // Set alternative default vars, where C is the lowercase alphabet
 v        // Make the implicit input lowercase and reassign it
oC ‰ eUq
oC        // Remove all items from the input that are not in the alphabet
   ‰     // Split into chars and select unique array items
      eUq // Check if the result is equal to the input split into chars

Essayez-le ici.

Lente
la source
2

MATL , 9 octets

kt2Y2X&X=

Essayez-le en ligne!

k   % Lowercase implicit input
t   % Duplicate that
2Y2 % Push lowercase alphabet
X&  % Intersection of alphabet and duplicate lowercase input
X=  % Check for exact equality.
Sanchises
la source
2

Japt 2.0, 12 11 bytes

-1 byte thanks to Nit

v
f\l â eUq

Test it online!

Oliver
la source
Uh, why did you change the version to a longer one? Also, I think the last version of Japt is 1.4.4...
Erik the Outgolfer
@EriktheOutgolfer The original didn't account for numbers automatically returning false.
Oliver
Ah, so you used an alpha version because it's actually shorter.
Erik the Outgolfer
@EriktheOutgolfer Right. The regex would've cost +2 in vanilla Japt. ethproductions.github.io/japt/…
Oliver
1
@Nit Thanks! Good use of e
Oliver
2

JavaScript (Node.js), 29 25 bytes

s=>!/(.).*\1|\d/i.test(s)

Try it online!

Thanks for the update on answer to @BMO , @l4m2 , @KevinCruijssen

-4 bytes thanks to @KevinCruijssen


la source
s=>!/(.).*\1|[^a-z]/i.test(s)?
l4m2
@KevinCruijssen : I didn't see the updated version
I'm pretty sure [^a-z] can be replaced with \d
Kevin Cruijssen
@KevinCruijssen : Thanks. updated
2

Retina, 16 bytes

Ci`(.).*\1|\d
^0

Returns 1 as Truthy and 0 as Falsey values.
Thanks @Neil for discovering and fixing a bug in my initial code.

Try it online.

Explanation:

C             Check if the input matches part of the following regex:
 i`            Case insensitivity enabled
               Check if part of the input matches either:
  (.)           A character `C`
     .*         followed by zero or more characters
       \1       followed by the same character `C` again
         |     Or
          \d    A digit
^0             Invert Truthy/Falsey, basically replacing every 0 with a 1,
               and every other value with a 1
Kevin Cruijssen
la source
Why is yours opposite ?
Muhammad Salman
@MuhammadSalman Two reasons: reversing the matches would cost more bytes. And I'm not too skilled with Retina so I'm not sure how to reverse the matches to begin with.. xD
Kevin Cruijssen
reason 1). Ah ok. reason 2). LOL
Muhammad Salman
1

PowerShell, 91 bytes

param($b)($a=[char[]]$b.ToUpper()|group|sort c*)[0].Count-eq$a[-1].count-and$b-notmatch'\d'

Try it online!

Naive solution, but I can't come up with a better algorithm. Takes input $b, converts it ToUppercase, casts it as a char-array. Pipes that array into Group-Object which constructs a object that has name/count pairs for each input letter. We then sort that based on the count and take the 0th one thereof. We check that its .Count is -equal to the .Count of the last [-1] pair. If so, then the counts are all equal, otherwise we have a different amount of letters.

We then -and that with checking whether the input -notmatches against \d to rule out any digits in the input. That Boolean result is left on the pipeline and output is implicit.

AdmBorkBork
la source
1

Python 2, 57 56 bytes

x=input().lower()
print len(set(x)-set(`763**4`))/len(x)

Try it online!

First it turn then input into a set, removing the duplicates, then remove the digits (encoded in `763**4`), then check if the length is the same as the original input

Rod
la source
1

Java 8, 61 39 bytes

s->!s.matches("(?i).*((.).*\\2|\\d).*")

Explanation:

Try it online.

s->  // Method with String parameter and boolean return-type
  !s.matches("(?i).*((.).*\\2|\\d).*")
     //  Return whether the input does not match the regex

Regex explanation:

String#matches implicitly adds ^...$.

^(?i).*((.).*\2|\d).*$
 (?i)                      Enable case insensitivity
^    .*                    Zero or more leading characters
       (       |  )        Followed by either:
        (.)                 Any character `C`
           .*               with zero or more characters in between
             \2             followed by that same character `C` again
               |           Or:
                \d          Any digit
                   .*$     Followed by zero or more trailing characters
Kevin Cruijssen
la source
1

APL (Dyalog Unicode), 12 bytes

Anonymous tacit function.

(∪≡~∘⎕D)819

Try it online!

819⌶ lowercase

() apply the following tacit function on that:

~∘⎕D remove Digits from the argument

∪≡ are the unique elements of the argument identical to that?

Adám
la source
1

Perl 6, 22 bytes

{!(.uc~~/(.).*$0|\d/)}

Try it online!

No matches for some character then later the same character. Implicit function as a code block, match implicitly on $_, invert book with !. Added |\d (ta Adam) but also needed .uc~~, which needed parentheses...

Alternative with Bags, 23 bytes

{.uc.ords.Bag65..97}

Try it online!

This one normalises case then makes a bag (set with incidence counts). Subset or equal only true if all members are members of the comparison Bag, and all incidence counts are less than or equal to those in the comparison Bag. So any repeats or digits would make the comparison false.

Phil H
la source
Fails on abc1.
Adám
Ah, wrote this answer before the numbers spec was added.
Phil H
Can;t you just add |\d?
Adám
@Adám: Sort of. Realised it also didn't detect repeated letters if the cases of those letters was different, so needed to normalise case and add parens as well.
Phil H
1
19 bytes
Jo King
1

Swift, 81 bytes

let s=readLine()!.lowercased().characters;print(s.count<1||Set(s).count==s.count)

Try it online!

Tamás Sengel
la source
Nice! 25 bytes shorter than mine.
onnoweb
1

Visual Basic for Applications (32 bit), 102 bytes

s=LCase(InputBox(u)):j=1:For i=1To Len(s):k=Mid(s,i,1):j=j*0^Instr(i+1,s,k)*(k Like"[a-z]"):Next:?j<>0

Used the fact that in VBA 0^x yields 1 if x is zero and 0 otherwise. Run in immediate (debug) window.

Edit: as pointed out by Taylor in the comments this only works in 32 bit installs of MS Office.

dnep
la source
If you restrict your language to Excel VBA, then you can swap this over to s=LCase([A1]):j=1:For i=1To Len(s):k=Mid(s,i,1):j=j*0^InStr(i+1,s,k)*(k Like"[a-z]"):Next:?j<>0 for 95 bytes by taking input from [A1]. Also, it is worth noting that because Exponentiation in VBA is weird that this solution is restricted to 32 bit installs of office.
Taylor Scott
Also, you can make your answer look better and more readable by using proper capitalization (see above) and adding a <!-- language-all: lang-vb --> flag to your answer to add syntax highlighting
Taylor Scott
1
@TaylorScott thanks! Added syntax highlighting and noted de 32 bit restriction. About the Excel input, I'd rather keep the solution application-invariant whenever possible.
dnep
1

05AB1E, 4 bytes

lDÔQ

Try it online!

Explanation

l      # convert input to lowercase
 D     # duplicate and push to stack
  Ô    # uniquify the list of characters
   Q   # check for equality
LordColus
la source
This fails if the input contains non-letter characters.
Shaggy
This works
LordColus
The input will only contain letters and/or numbers, no spaces ([a-zA-Z0-9])
LordColus
"An isogram is a word consisting only of letters with no duplicates" - i.e., "words" containing numbers should return a falsey value. See the 5th test case for an example.
Shaggy
My bad. See @Enigma's answer for the correct 05AB1E code.
LordColus
1

C (gcc), 87 85 83 bytes

f(s,p,b,P)char*s,*p;{for(b=s;*s;++s)for(p=b*=*s>64;b&&p<s;b=(*s^*p++)&95?b:0);s=b;}

Try it online!

Jonathan Frech
la source
@ceilingcat Fine suggestion, thanks.
Jonathan Frech
@ceilingcat Thank you.
Jonathan Frech
0

CJam, 11 bytes

qelA,s+_L|=

Try it online!

Explanation

The basic idea is to append each digit then check for duplicates. Since the append ensures that each digit is already present once, any further presence of digits will be a duplicate, causing it to return false.

q      e# read the input:            | "MOoSE1"
el     e# convert to lowercase:      | "moose1"
A      e# push 10:                   | "moose1" 10
,      e# range [0,N):               | "moose1" [0 1 2 3 4 5 6 7 8 9]
s      e# string representation:     | "moose1" "0123456789"
+      e# concatenate:               | "moose10123456789"
_      e# duplicate:                 | "moose10123456789" "moose10123456789"
L|     e# union with the empty list: | "moose10123456789" "mose1023456789"
       e# (this gets rid of duplicates)
=      e# Equal to original:         | 0
Esolanging Fruit
la source
0

Red, 76 bytes

func[s][a: charset[#"a"-#"z"#"A"-#"Z"]parse s[any[copy c a ahead not to c]]]

Try it online!

Galen Ivanov
la source
0

Smalltalk, 57 bytes

Method to be defined in class String:

s^(self select:#isLetter)asUppercase asSet size=self size

This is most likely self-explanatory.

Hans-Martin Mosner
la source
0

Pyth, 17 bytes

.Am&!t/rz0d}dGrz0

Test suite

Explanation:
.Am&!t/rz0d}dGrz0 # Code
  m           rz0 # Map the following over the lowercase input:
      /rz0d       #  Count occurrences of d in lowercase input
     t            #   minus 1
    !             #    inverted (0 -> True)
   &              #     and
           }dG    #      d is in the lowercase alphabet
.A                # Print whether all values are truthy
Python 3 translation:
z=input()
print(all(map(lambda d:not z.lower().count(d)-1and d in "abcdefghijklmnopqrstuvwxyz",z.lower())))
hakr14
la source
0

C#, 82 bytes

bool f(string s)=>!!(s.GroupBy(c=>c).Any(c=>c.Count()>1|(!Char.IsLetter(c.Key))));

edit: added test for char

edit: using GroupBy to shorten it by 5 byte

Raymond Osterbrink
la source
1
Welcome to PPCG! I think you're missing the requirement that you also need to check that the input contains no digits.
Martin Ender
0

APL (Dyalog Unicode), 25 20 22 bytes

'''(.).*\1|\d'S'&'1

Try it online!

Returns 1 for true, else 0.

Saved 5 bytes thanks to @H.PWiz

Fixed, and saved another byte thanks to @Adám

How?

'''(.).*\1|\d'S'&'1  Tacit fn
                    1  Ignore case
               S'&'    Search and return the match(es)
   '(.).*\1|\d'         For this regex
''                     And compare to the empty string
J. Sallé
la source
Fails on abc1.
Adám
Isn't \w. valid?
Adám
If you mean (.).*\1, no. It also fails for abc1 :/
J. Sallé
I don't understand. What do you mean by "it also fails"?
Adám
If you Try it Online! you can see it returns 1 for abc1, when it should return 0.
J. Sallé
0

Tcl, 114 bytes

proc I w {lmap c [set L [split $w ""]] {if {[regexp -all -nocase $c $w]>1|![string is alp $c]} {return 0}}
expr 1}

Try it online!

Tcl, 121 bytes

proc I w {lmap c [set L [split $w ""]] {if {[llength [lsearch -al -noc $L $c]]>1|![string is alp $c]} {return 0}}
expr 1}

Try it online!

Still too long for my taste!

sergiol
la source