Verifique se as letras da palavra estão em ordem alfabética

37

Escreva uma função / programa que aceite uma sequência de letras maiúsculas / minúsculas [A-Za-z] como entrada, que verifique se as letras existentes são únicas e em ordem alfabética (ignorando maiúsculas e minúsculas) ou não. A saída deve ser verdadeira se for única e em ordem alfabética e, se não for, falsificada.

Aqui alguns casos de teste

a                           true
abcdefGHIjklmnopqrSTUVWXyz  true     
aa                          false
puz                         true
puzz                        false
puzZ                        false
puZ                         true
PuZ                         true
pzu                         false
pzU                         false
abcdABCD                    false
dcba                        false

Se você quiser, execute seu programa com todas as palavras de uma lista de palavras como esta e poste algumas interessantes =).

Ponto

O menor número de bytes vence.

flawr
fonte
3
Casos de teste fracos. (Veja o meu comentário sobre Richard A 's resposta PHP .)
manatwork
O alfabeto dá laços? Deve zaser um valor verdadeiro?
MayorMonty
Não, o alfabeto começa com ae termina com z.
flawr
Você deve ter alguns casos de teste que não estão em ordem alfabética
Jo King
11
@JoKing eu adicionei alguns.
flawr 5/03

Respostas:

28

CJam, 8 bytes

lel_$_&=

Aqui está um equipamento de teste para todos os exemplos no desafio. Isso retorna 0or 1(que são falsy e truth, respectivamente, em CJam).

E aqui está um script para filtrar a lista de palavras na pergunta (leva alguns segundos para executar). Você precisará copiar a lista de palavras no campo de entrada manualmente, porque é muito longo para um link permanente.

Explicação

l        "Read input.";
 el      "Convert to lower case.";
   _$    "Get a copy and sort it.";
     _&  "Remove duplicates (by computing the set intersection with itself).";
       = "Check for equality with original (lower case) word.";
Martin Ender
fonte
21

Regex (qualquer sabor), 55 bytes

Algumas pessoas não consideram o regex uma linguagem de programação, mas já foi usada antes e não está perto de ser a mais curta.

^a?b?c?d?e?f?g?h?i?j?k?l?m?n?o?p?q?r?s?t?u?v?w?x?y?z?$

Adicionei um byte para o isinalizador (sem distinção entre maiúsculas e minúsculas). Isso é muito simples e pode ser mais curto para gerar em tempo real.

Se regex sozinho não for permitido, você poderá usar este programa Retina de 56 bytes sugerido por Martin Büttner:

i`^a?b?c?d?e?f?g?h?i?j?k?l?m?n?o?p?q?r?s?t?u?v?w?x?y?z?$

Ao executá-lo na lista de palavras vinculada acima, obtivemos 10 palavras de 6 letras em ordem alfabética.

["abomina", "quase", "começa", "mendiga", "bijoux", "biópsia", "chimpanzé", "chinos", "chintz", "fantasma"]

NinjaBearMonkey
fonte
2
Você pode usar Retina vez de ES6 se alguém reclama que regex não é um idioma:i`^a?b?c?d?e?f?g?h?i?j?k?l?m?n?o?p?q?r?s?t?u?v?w?x?y?z?$
Martin Ender
@ MartinBüttner eu tinha esquecido a Retina. Obrigado!
#
@ MartinBüttner De acordo com o META ( meta.codegolf.stackexchange.com/questions/2028/… ), os regexes podem ser 'vistos' um pouco como uma linguagem de programação.
Ismael Miguel
@IsmaelMiguel eu sei. E, de fato, essa definição foi escolhida especificamente para garantir que não exclua a expressão regular. Mas algumas pessoas ainda reclamam regularmente, porque você não pode usar regex como qualquer outro idioma.
Martin Ender
@ MartinBüttner Quem se queixa pode ir a um local chamado META e procurar por ele. Por que ninguém visita um lugar tão bonito, cheio de perguntas que resolvem a maioria dos problemas?
Ismael Miguel
19

Python 3, 44 bytes

*s,=input().lower()
print(sorted(set(s))==s)

Uma abordagem simples - verifique a exclusividade, verifique a classificação.

Sp3000
fonte
Você pode explicar o que *s,=...faz?
flawr
@flawr Isso é chamado de 'atribuição com estrela'. Nesse código, ele simplesmente converte o lado direito em uma lista. É o mesmo que s=list(input().lower()).
Jakube
11
@flawr Como Jakube diz, aqui está apenas convertendo a entrada em uma lista de caracteres. Em geral, é uma sintaxe de atribuição especial que permite fazer coisas como x,*y = [1, 2, 3, 4], que atribui 1 a xe [2, 3, 4]a y.
Sp3000
@ mbomb007 *s,= is list(s) ... link
Sp3000
Você pode fazer em {*s}vez de set(s)salvar 2 bytes.
mbomb007
12

> <> , 52 42 39 bytes

0>i:1+?v1n;
? )'`':/'@'v
0v?){:-<'`'/;n

Esse tipo de pergunta é um dos poucos tipos com os quais> <> é bastante confortável, pois precisamos lidar apenas com um caracter por vez.

Explicação

Não se perca! Há muita embalagem aqui.

0            Push 0. We'll be mapping a-z to 1-26, so 0 will be smaller than everything

(loop)
i            Read a char of input
:1+? 1n;     If there's no more input, print 1
:'`')?       If the char is bigger than backtick...
  '`'          Push backtick  (which is one before 'a'), else...
  '@'          Push an @ sign (which is one before 'A')
-            Subtract, mapping a-z to 1-26
:{)?         If the new char is bigger than the previous char...
               Repeat from the beginning of the loop, else...
  0n;          Print 0

Solução anterior, 42 bytes

0i:1+?v1n;n0/\!
?)'`':/'@'v
? ){:-<'`'/ vv

O interessante é que, apesar de parecer ter a mesma funcionalidade, a alternativa

0i:1+?v1n;n0\/!
?)'`':/'@'v
? ){:-<'`'/ ^^

(A mudança está nas setas e espelhos na extrema direita)

na verdade, fornece resultados incorretos , devido ao intérprete de> <> usando um comando padrão do Python. O que acontece é que, percorrendo o espaço vazio no final da segunda linha, os 0s são implicitamente colocados nos espaços em branco quando> <> tenta acessar a célula. Isso mexe com o ?trampolim condicional no início da mesma linha, pois os 0s recém-colocados são ignorados e não vno final.

Sp3000
fonte
Eu sinto que você poderia economizar alguns bytes de apenas subtraindo 32 a partir de letras minúsculas em vez de obter índice alfabético para todas as letras
Aaron
9

Haskell, 52 bytes

import Data.Char
and.(zipWith(>)=<<tail).map toLower

Uso: (and.(zipWith(>)=<<tail).map toLower) "abcd"quais saídas True.

nimi
fonte
9

C, 67 65 57 54 (52) caracteres

f(char*s){int c,d=0;for(;(c=*s++)&&(c&~32)>(d&~32);d=c);return!c;}

um pouco mais curto:

f(char*s){int c,d=0;for(;(c=*s++)&&(c&~32)>d;d=c&~32);return!c;}

e ainda mais curto:

f(char*s){int d=32;for(;(*s|32)>d;d=*s++|32);return!*s;}

Aqui está um pequeno teste: http://ideone.com/ZHd0xl

Após as sugestões mais recentes, ainda há duas versões mais curtas:

// 54 bytes
f(char*s){int d=1;for(;(*s&=95)>d;d=*s++);return!*s;}

// 52, though not sure if valid because of global variable
d;f(char*s){d=1;for(;(*s&=95)>d;d=*s++);return!*s;}

Além disso, esse código depende do fato de que, em ASCII, letras minúsculas e maiúsculas diferem apenas pelo quinto bit (32) que eu filtro. Portanto, isso pode não funcionar com outras codificações, obviamente.

EDIT: A versão mais recente sempre define o quinto bit como |32é menor que &~32.

Felix Bytow
fonte
Bom uso do conhecimento do domínio para lidar com o problema de distinção entre maiúsculas e minúsculas.
precisa saber é o seguinte
Salve 2 substituindo o loop for por for(;(*s&=95)>d;d=*s++);. E você pode inicializar da 1sem alterar o resultado, economizando mais 1. Vejo.
AShelly
11
Não tenho certeza se isso é considerado legal no código golf, mas d;f(char*s){d=32;for...}funciona, declarando dimplicitamente como um int global (que, no GCC, é um aviso - "a definição de dados não tem tipo ou classe de armazenamento" - mas não é um erro). Isso economiza dois bytes.
wchargin
AShelly hm, não considerou isso. Sua sugestão altera a string original. Mas seja como for, é código golf: D Também não tenho certeza sobre a dica do WChargin como d como uma variável global não seria realmente parte da função.
Felix Bytow
11
Por que não inicializar dno forloop, em vez de sua própria declaração? Dessa forma, você salva ;.
Josh
6

Ruby, 33

->s{c=s.upcase.chars
c==c.sort|c}

Verifica se os caracteres exclusivos classificados são iguais a todos os caracteres.

britishtea
fonte
11
Pense que você pode obtê-lo um pouco mais curto comc==c.sort|c
histocrat
Ooh, eu gosto disso, isso é inteligente. Obrigado.
britishtea
5

Javascript (ES5), 101

function i(s){b=0;l=''.a
s.toUpperCase().split('').forEach(function(c){if(c<=l)b=1
l=c})
return!b}

Aprimorado para 87 por edc95:

voto o seu comentário :)

function i(s){return!s.toUpperCase().split(l='').some(function(c){return(u=l,l=c)<=u})}

Aliás, os casos de teste atualmente no OP são preenchidos se um programa está apenas verificando a exclusividade, desconsiderando a ordem.


Ainda não posso escrever comentários, então vou responder algumas observações aqui:

@ edc65: Obrigado! Tentei reescrevê-lo usando some(), mas não consegui uma solução mais curta, porque, embora pareça que me permita me livrar da variável supérflua b, você precisa digitar "return" duas vezes (o mesmo com reduce()) e você não pode simplesmente retornar o resultado da comparação diretamente, porque o último caractere precisa ser salvo após a comparação com ele.

@ edc65: Esse é um bom uso do operador de vírgula para 87! Editei-o na minha resposta para obter mais visibilidade.

Tamas
fonte
Essa é uma ideia melhor que a minha. Usando .alguns poderia ser ainda melhor (52 com ES6)
edc65
Você pode remover o espaço entre returne !bsalvar um caractere.
ProgramFOX
Como é, o espaço em branco apenas carinho, 96:function i(s){b=0;l='';s.toUpperCase().split('').forEach(function(c){if(c<=l)b=1;l=c});return!b}
edc65
O mesmo, mais function i(s){s.toUpperCase(b=0).split(l='').forEach(function(c){if(c<=l)b=1;l=c});return!b}
golfe
11
Usando alguma (ou todas as mesmas pontuações), 87:function i(s){return!s.toUpperCase().split(l='').some(function(c){return(u=l,l=c)<=u})}
edc65
4

Haskell, 90 bytes

Fornece a função f :: String -> Bool

import Data.List
import Distribution.Simple.Utils
f l=g$lowercase l
g l=sort l==l&&l==nub l

Uso (supondo que ele seja salvo como golf.hs). ...é usado para substituir ghcias mensagens de carregamento detalhadas de.

$ ghci golf.hs
...
*Main> f "as"
...
True
*Main> f "aa"
False

Se alguém tiver um lowercasemétodo mais curto do que import Distribution.Simple.Utilsentão, por favor, comente.

HEGX64
fonte
11
Use map toLowerfrom em Data.Charvez delowercase
nimi
11
Além disso: você pode remover o parâmetro lem f, ie f=g.lowercase(ou f=g.map toLowerse você alternar para toLower). Dentro de guma comparação é suficiente: g l=nub(sort l)==l.
nimi
4

Wolfram Mathematica, 49 37 bytes

f[x_]:=(l=Characters[ToLowerCase[x]];Union[l]==l)

Solução PS Shorter de Martin Büttner:

Union[l=Characters@ToLowerCase@#]==l&
Savenkov Alexey
fonte
2
#⋃#==#&@*Characters@*ToLowerCase
precisa saber é o seguinte
11
@alephalpha Isso é lindo!
Martin Ender
4

J, 17 bytes

Verifica se as minúsculas classificadas /:~ string é igual -:à ~.string nub em minúsculas .

   (/:~-:~.)@tolower

   NB. testing with the example inputs
   ((/:~-:~.)@tolower) every (1$'a');'abcdefGHIjklmnopqrSTUVWXyz';'aa';'puz';'puzz';'puzZ';'puZ';'PuZ'
1 1 0 1 0 0 1 1

Como em J, uma "string" longa de 1 caractere, representada como uma string regular (com aspas), é apenas um átomo de caracteres, não uma string real. (No exemplo acima eu usei 1$'a'.)

randomra
fonte
4

MATLAB, 29 27 bytes

Agora, uma linha única que até faz sentido fora do código-golfe.

Como uma função anônima (use as o('yourstring'))

o=@(s)all(diff(lower(s))>0)

Eu acho que essa função é bastante auto-explicativa, pois se parece com um anúncio de jornal.

Versão anterior (29 bytes):

all(diff(lower(input('')))>0)

A entrada deve ser apresentada entre 'marcas, por exemplo 'Potato'.

Sanchises
fonte
4

Braquilog , 3 bytes

ḷ⊆Ạ

Experimente online!

O predicado será bem-sucedido se a entrada atender aos requisitos descritos e falhar se não atender, imprimir true.ou false.se executar como um programa.

       The input,
ḷ      lowercased,
 ⊆     is a not-necessarily-contiguous sub-list of
  Ạ    "abcdefghijklmnopqrstuvwxyz".

A primeira versão que criei, sem referenciar explicitamente o alfabeto:

Braquilog , 4 bytes

ḷ≠.o

Experimente online!

        The input,
ḷ       lowercased,
 ≠      in which every character is distinct,
  .     is the output variable,
   o    which sorted,
        is still the output variable.
String não relacionada
fonte
3

J, 21 caracteres

Este é muito longo. O argumento deve ter classificação 1, ou seja, deve ser uma string ou vetor.

*/@(<=~.;/:~)@tolower
  • tolower y- yem minúsculas.
  • /:~ y- yem ordem lexical.
  • ~. y- o nó de y, isto é, ycom duplicatas removidas.
  • x ; y- xe ycoloque em caixas e depois concatenadas.
  • < y- ycoloque em uma caixa.
  • x = y- x comparado com elementos y.
  • (< y) = (~. y) ; (/:~ y)- um vetor indicando se yé igual ao seu nó e ele próprio classificado.
  • */ y- o produto dos itens de y, ou sua lógica e se os itens são booleanos.
  • */ (< y) = (~. y) ; (/:~ y)- um booleano indicando a propriedade desejada para minúsculas y.
FUZxxl
fonte
3

Julia, 44 bytes

s->(l=lowercase(s);l==join(sort(unique(l))))

Isso cria uma função anônima que aceita um único argumento s, converte-o para minúsculas e o compara à versão classificada exclusiva da string. Retorna um booleano, trueou seja, ou false. Se você quiser testá-lo, atribua-o como f=s->...e depois ligue f("PuZ")etc.

Alex A.
fonte
Amém, @flawr. Obrigado pelo apoio.
Alex A.
3

Pure Bash 4.x, 37

[[ ${1,,} =~ ^`printf %s? {a..z}`$ ]]

Entrada tomada como um parâmetro da linha de comandos. De acordo com a semântica padrão do shell, o código de saída 0 significa verdadeiro (alfabético) e o código de saída! = 0 significa falso (não alfabético).

O printf cria o regex como na solução do @ hsl . A sequência de entrada é expandida para minúscula e comparada com a regex.


Resposta anterior:

Bash + coreutils, 52

Solução simples:

a=`fold -1<<<${1,,}`
cmp -s <(sort -u<<<"$a")<<<"$a"
Trauma Digital
fonte
Observe que isso requer o bash 4.x.
Re
@MarkReed Sim. Notado.
Digital Trauma
3

C # 6, 18 + 82 76 = 94 bytes

Requer (18 bytes):

using System.Linq;

Código (76 bytes):

bool a(string s)=>(s=s.ToLower()).Distinct().OrderBy(x=>x).SequenceEqual(s);

O C # 6 suporta lambdas para definir uma função, útil para jogar golfe.

Versão não C # 6:

bool a(string s){return (s=s.ToLower()).Distinct().OrderBy(x=>x).SequenceEqual(s);}

Código não destruído:

bool IsInAlphabeticalOrder(string s)
{
    s = s.ToLower();
    return s.Distinct()
            .OrderBy(x => x)
            .SequenceEqual(s);
}
ProgramFOX
fonte
3

JavaScript (ES6) 54

Converta em maiúsculas e depois em matriz e classificação. Se durante a classificação dois elementos estiverem na ordem errada ou igual, retorne 0 (falsy) else 1 (truth)

Editar encurtado thx para @Optimizer (mas ainda 2 mais do que a solução @Tamas implementado em ES6: F=s=>[...s.toUpperCase()].every(c=>(u=l,l=c)>u,l=''))

F=s=>[...s.toUpperCase(x=1)].sort((a,b)=>a<b?1:x=0)&&x

Teste no console Firefox / FireBug

;['a','abcdefGHIjklmnopqrSTUVWXyz','aa','puz','puzz','puzZ','puZ','PuZ']
.map(w=>w+' '+F(w))

["a 1", "abcdefGHIjklmnopqrSTUVWXyz 1", "aa 0", "puz 1", "puzz 0", "puzZ 0", "puZ 1", "PuZ 1"]

edc65
fonte
11
s=parece não ser necessário ...
Optimizer
@Optimizer direita, foi uma primeira tentativa quando finalmente i comparado o original (uppercased) eo classificadas
edc65
3

C (44 bytes)

f(char*s){return(*s&=95)?f(s+1)>*s?*s:0:96;}

Teste aqui: http://ideone.com/q1LL3E

Postando isso porque ainda não posso comentar, caso contrário, seria uma sugestão para melhorar a resposta C existente porque roubei completamente a ideia que não diferencia maiúsculas de minúsculas da resposta C existente.

Retorna 0 se a sequência não for solicitada e um valor diferente de zero se solicitado.

erai
fonte
3

Golang (65 bytes)

Go não é uma linguagem amigável para golfe, também, eu sou péssima em golfe ...

func a(s[]byte)(bool){return len(s)<2||s[0]|32<s[1]|32&&a(s[1:])}

Execute-o aqui: http://play.golang.org/p/xXJX8GjDvr

editar 106-> 102

editar 102-> 96

editar 96-> 91

editar 91-> 87

editar 87-> 65

Eu venci a versão java, posso parar por hoje

Kristoffer Sall-Storgaard
fonte
3

Java 8-90 89 87 85 caracteres

A idéia aqui é usar uma função 'reduzir' que rastreie o último caractere e "desista" quando detectar que a sequência não está subindo estritamente.

golfed:

int f(String s){return s.toLowerCase().chars().reduce(0,(v,c)->(v<0)?v:(c>v)?c:-1);}

ungolfed:

int f(String s){
    return s.toLowerCase()
            .chars()
            .reduce(0, (v,c) -> (v<0)? v : (c>v)?c:-1);
}

exemplo:

System.out.println(new Quick().f("abc"));
System.out.println(new Quick().f("aa"));
System.out.println(new Quick().f("abcdefGHIjklmnopqrSTUVWXyz"));
System.out.println(new Quick().f("puZ"));
System.out.println(new Quick().f("Puz"));
System.out.println(new Quick().f("cba"));

saída:

99
-1
122
122
122
-1
Michael Easter
fonte
3

Perl 6, 35 bytes

{my@c=.uc.comb;@c [email protected]}

Isso produz um bloco que pode ser chamado; se eu pudesse assumir que $_já está definido com a palavra desejada, eu poderia excluir as chaves ao redor e perder mais dois bytes, mas provavelmente a única maneira razoável de fazer essa suposição seria executá-la -ne alimentá-la como entrada padrão , que adicionaria os dois bytes de volta.

Mark Reed
fonte
Claro que sim. .uc.combnão reorganiza nada; portanto, se a matriz maiúscula e penteada for igual à matriz maiúscula e penteada classificada , isso significa que ela começou na ordem classificada.
Mark Reed
certo, está verificando o tamanho da interseção, o que ignora a ordem. Ok, atualizado.
Mark Reed
3

R , 37 bytes

all(diff(utf8ToInt(scan(,''))%%32)>0)

Experimente online!

Postagem, pois isso é substancialmente diferente e mais curto que a resposta R de Michal .

Converte as letras em pontos de código ASCII com o utf8ToIntmódulo 32, para que as letras maiúsculas e minúsculas sejam convertidas nos mesmos números 1 ... 26. Calcula as diferenças aos pares e verifica se todas são positivas.

Robin Ryder
fonte
2

Perl, 27

O regexp do @ hsl cria dinamicamente.

#!perl -p
$"="?";@x=a..z;$_=/^@x?$/i

Também podemos fazer uma correspondência inversa: converter a entrada em um regexp: PuZ=> .*p.*u.*z.*e depois corresponder isso a uma sequência de letras em ordem alfabética. Resultado - também 27 caracteres.

#!perl -lp
$_=join(s//.*/g,a..z)=~lc
nutki
fonte
2

k (6 bytes)

&/>':_

& retorna true se os dois argumentos forem verdadeiros

/modifica &para aplicar "sobre" uma lista, como uma dobra em idiomas funcionais

> Melhor que

':modifica >para aplicar "each-prior", então retorna um vetor de booleanos informando quais elementos são maiores que seu antecessor

_ torna argumento minúsculo

  _"puzZ"
"puzz"
  >':_"puzZ"
1110b
  &/>':_"puzZ"
0b

( 0bsignifica booleano false)

q (13 bytes)

all(>':)lower

q é apenas açúcar sintático em k. allé definido como &/e menor é_

mollmerx
fonte
4
Você pode explicar como isso funciona?
flawr
Quase parece trapaça em outros idiomas ... Quem precisa de nomes de funções, parênteses e ponto e vírgula? :)
Sanchises 02/02
O @sanchises k tem todas essas coisas e elas funcionam da mesma maneira que nas linguagens do estilo C. Acontece que esse problema é expressável como uma única declaração.
mollmerx
2

Python, 50 bytes

f=lambda x:sorted(set(x.lower()))==list(x.lower())

Experimente online aqui: http://repl.it/c5Y/2

mbomb007
fonte
2

VBA (161 bytes)

Function t(s As String)
t = 0
For i = 2 To Len(s)
a = Left(LCase(s), i)
    If Asc(Right(a, 1)) <= Asc(Right(a, 2)) Then Exit Function
Next
t = 1
End Function  

Compara o valor ascii com a letra anterior em minúscula, retorna 0 (false) quando seu valor é menor / igual e sai da função

Alex
fonte
2

Python 2 , 43 bytes

lambda s:eval('"%s"'%'"<"'.join(s.lower()))

Experimente online!

Coloca <símbolos entre todas as letras (convertidas em minúsculas) e depois evals. Os operadores de comparação encadeados do Python ficam perfeitamente felizes em avaliar a coisa toda como uma grande expressão booleana.

ArBo
fonte
1

Erlang, 51

f(S)->G=string:to_lower(S),ordsets:from_list(G)==G.

Usa um conjunto ordenado (análogo ao java.util.TreeSet ) para classificar os caracteres e descartar as duplicatas. A nova lista é então comparada com a sequência de entrada.

Função de teste:

test() ->
    [io:format("~p ~p~n", [S, f(S)]) || S <- ["a","abcdefGHIjklmnopqrSTUVWXyz","aa","puz","puzz","puzZ","puZ","PuZ"]].
cPu1
fonte
1

Java, 96

boolean a(char[]a){int i=-1,l=0;for(;++i<a.length;l+=i>0&&a[i]<=a[i-1]?1:0)a[i]|=32;return l<1;}

Bem simples aqui. Apenas converta tudo para menor e compare cada um com o caractere anterior.

Geobits
fonte