Controlla se le lettere della parola sono in ordine alfabetico


37

Scrivi una funzione / programma che accetta una stringa di lettere minuscole / maiuscole [A-Za-z] come input, che controlla se le lettere occorrenti sono uniche e in ordine alfabetico (ignorando le lettere maiuscole e minuscole) o meno. L'output deve essere veritiero se sono unici e in ordine alfabetico e falsi in caso contrario.

Ecco alcune prove

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 vuoi, esegui il tuo programma su tutte le parole di un elenco di parole come questo e pubblica alcuni interessanti =).

Punto

Vince il numero più basso di byte.


3
Casi di test deboli. (Vedi il mio commento su Richard A 's risposta PHP .)
manatwork

L'alfabeto scorre? Dovrebbe zaessere un valore veritiero?
MayorMonty,

No, l'alfabeto inizia con ae termina con z.
flawr

Dovresti avere alcuni casi di test che non sono in ordine alfabetico
Jo King

1
@JoKing Ne ho aggiunti alcuni.
flawr

Risposte:


28

CJam, 8 byte

lel_$_&=

Ecco un test harness per tutti gli esempi nella sfida. Questo ritorna 0o 1(che sono rispettivamente falsa e verità in CJam).

Ed ecco uno script per filtrare l'elenco delle parole nella domanda (l'esecuzione di alcuni secondi). Dovrai copiare manualmente l'elenco delle parole nel campo di input, perché è troppo lungo per un permalink.

Spiegazione

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.";

21

Regex (qualsiasi sapore), 55 byte

Alcune persone non considerano regex un linguaggio di programmazione, ma è stato usato in precedenza e non è vicino al più breve.

^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?$

Ho aggiunto un byte per il i flag (senza distinzione tra maiuscole e minuscole). Questo è molto semplice e potrebbe essere più breve da generare al volo.

Se non è consentito regex da solo, è possibile utilizzare questo programma Retina a 56 byte suggerito da 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?$

L'esecuzione di questo nell'elenco di parole collegato sopra ha prodotto 10 parole di 6 lettere in ordine alfabetico.

["abhors", "quasi", "inizia", ​​"begirt", "bijoux", "biopsia", "scimpanzé", "chinos", "chintz", "ghosty"]


2
Puoi usare Retina invece di ES6 se qualcuno si lamenta che regex non è una lingua: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 Mi ero dimenticato di Retina. Grazie!
NinjaBearMonkey

@ MartinBüttner Secondo il META ( meta.codegolf.stackexchange.com/questions/2028/… ) i regexes possono essere "visti" in qualche modo come un linguaggio di programmazione.
Ismael Miguel,

@IsmaelMiguel Lo so. E in effetti quella definizione è stata scelta appositamente per assicurarsi che non escluda regex. Ma alcune persone si lamentano ancora regolarmente, perché non puoi usare regex come qualsiasi altra lingua.
Martin Ender,

@ MartinBüttner Chi si lamenta può recarsi in un posto chiamato META e cercarlo. Perché nessuno visita un posto così bello pieno di domande che risolvono la maggior parte dei problemi?
Ismael Miguel,

19

Python 3, 44 byte

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

Un approccio semplice: controlla l'unicità, controlla l'ordinamento.


Puoi spiegare cosa *s,=...fa?
flawr

@flawr Questo si chiama "assegnazione speciale". In questo codice, converte semplicemente il lato destro in un elenco. È lo stesso di s=list(input().lower()).
Jakube

1
@flawr Come dice Jakube, qui sta solo convertendo l'input in un elenco di caratteri. In generale, si tratta di una sintassi speciale incarico che ti permette di fare le cose come x,*y = [1, 2, 3, 4], che assegna a 1 xe [2, 3, 4]a y.
Sp3000

@ mbomb007 *s,= is list(s) ... link
Sp3000

Puoi fare {*s}invece di set(s)salvare 2 byte.
mbomb007,

12

> <> , 52 42 39 byte

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

Questo tipo di domanda è uno dei pochi tipi a cui> <> è abbastanza a suo agio, poiché abbiamo solo bisogno di occuparci di un carattere alla volta.

Spiegazione

Non perderti! C'è molto da avvolgere qui.

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

Soluzione precedente, 42 byte

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

La cosa interessante è che, nonostante sembri avere la stessa funzionalità, l'alternativa

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

(Il cambiamento è nelle frecce e negli specchi all'estrema destra)

in realtà fornisce risultati errati , a causa dell'interprete> <> usando un parametro predefinito di Python. Quello che succede è che, attraversando lo spazio vuoto alla fine della seconda riga, gli 0 vengono inseriti implicitamente negli spazi vuoti quando> <> tenta di accedere alla cella. Questo quindi si confonde con il ?trampolino condizionale all'inizio della stessa riga, poiché gli 0 appena posizionati vengono saltati piuttosto che valla fine.


Sento che potresti salvare alcuni byte sottraendo solo 32 da lettere minuscole anziché ottenere l'indice alfabetico per tutte le lettere
Aaron,

9

Haskell, 52 byte

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

Utilizzo: (and.(zipWith(>)=<<tail).map toLower) "abcd"quali output True.


9

C, 67 65 57 54 (52) caratteri

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

un po 'più corto:

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

e ancora più breve:

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

Ecco un piccolo test: http://ideone.com/ZHd0xl

Dopo gli ultimi suggerimenti qui ci sono ancora due versioni più brevi:

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

Anche questo codice si basa sul fatto che in ASCII le lettere minuscole e maiuscole differiscono solo per il 5o bit (32) che filtro. Quindi questo potrebbe non funzionare con altre codifiche ovviamente.

EDIT: l'ultima versione imposta sempre il 5 ° bit in quanto |32è più breve di &~32.


Buon uso della conoscenza del dominio per gestire il problema della distinzione tra maiuscole e minuscole.
RomSteady

Salvare 2 sostituendo il ciclo for con for(;(*s&=95)>d;d=*s++);. E è possibile inizializzare dper 1senza cambiare il risultato, risparmiando 1 altro. Vedere.
AShelly,

1
Non sono sicuro che questo sia considerato legale nel code golf, ma d;f(char*s){d=32;for...}funziona, dichiarando dimplicitamente come un int globale (che, in GCC, è un avvertimento - "la definizione dei dati non ha tipo o classe di archiviazione" - ma non un errore). Ciò consente di risparmiare due byte.
wchargin

Ah, helly, non ci ho pensato. Tuttavia, il tuo suggerimento modifica la stringa originale. Comunque sia, si tratta di codice golf: D Inoltre, non sono sicuro del suggerimento di WChargin, in quanto una variabile globale non farebbe davvero parte della funzione.
Felix Bytow,

1
Perché non inizializzare dnel forciclo piuttosto che la propria istruzione? In questo modo salvi a ;.
Josh

6

Ruby, 33

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

Verifica se i caratteri univoci ordinati sono uguali a tutti i caratteri.


1
Pensi di poterlo abbreviare un po 'conc==c.sort|c
istocratico

Ooh, mi piace, è intelligente. Grazie.
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}

Migliorato a 87 da edc95:

vota il suo commento :)

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

A proposito, i casi di test attualmente in PO sono soddisfatti se un programma sta solo verificando l'unicità, ignorando l'ordine.


Non posso ancora scrivere commenti, quindi risponderò ad alcune osservazioni qui:

@ edc65: grazie! Ho provato a riscriverlo usando some(), ma non sono riuscito a ottenere una soluzione più breve, perché anche se sembra che mi consentirebbe di sbarazzarmi della variabile b superflua, è necessario digitare "return" due volte (lo stesso conreduce() ), e tu non può semplicemente restituire direttamente il risultato del confronto, poiché l'ultimo personaggio deve essere salvato dopo il confronto con esso.

@ Edc65: è un dell'operatore virgola per 87! L'ho modificato nella mia risposta per una maggiore visibilità.


È un'idea migliore della mia. L'uso di .some potrebbe essere ancora migliore (52 con ES6)
edc65

È possibile rimuovere lo spazio tra returne !bper salvare un carattere.
Programma FOX

Come è, solo uno spazio bianco attento, 96:function i(s){b=0;l='';s.toUpperCase().split('').forEach(function(c){if(c<=l)b=1;l=c});return!b}
edc65

Lo stesso, ha giocato di più, 92:function i(s){s.toUpperCase(b=0).split(l='').forEach(function(c){if(c<=l)b=1;l=c});return!b}
edc65

1
Usando alcuni (o tutti, stesso punteggio), 87:function i(s){return!s.toUpperCase().split(l='').some(function(c){return(u=l,l=c)<=u})}
edc65

4

Haskell, 90 byte

Fornisce la funzione f :: String -> Bool

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

Utilizzo (supponendo che sia salvato come golf.hs). ...è usato per sostituireghci i messaggi di caricamento dettagliati.

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

Se qualcuno ha un lowercasemetodo più corto di import Distribution.Simple.Utilsallora, per favore commenta.


1
Utilizzare map toLoweral Data.Charposto dilowercase
nimi

1
Inoltre: è possibile rimuovere il parametro lin f, ovvero f=g.lowercase(o f=g.map toLowerse si passa a toLower). Entro gun confronto è abbastanza: g l=nub(sort l)==l.
nimi

4

Wolfram Mathematica, 49 37 byte

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

Soluzione PS Shorter di Martin Büttner:

Union[l=Characters@ToLowerCase@#]==l&

2
#⋃#==#&@*Characters@*ToLowerCase
alephalpha

1
@alephalpha È bellissimo!
Martin Ender,

4

J, 17 byte

Verifica se la /:~stringa ordinata in minuscolo è uguale -:alla ~.stringa nub in minuscolo .

   (/:~-:~.)@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

Come in J una "stringa" lunga di 1 carattere rappresentata come una stringa normale (con virgolette) è solo un atomo di carattere, non una stringa reale, ho formattato l'input in modo appropriato, quindi tutti gli input sarebbero stringhe reali. (Nell'esempio sopra ho usato 1$'a'.)


4

MATLAB, 29 27 byte

Ora per un one-liner che ha senso anche al di fuori del code-golf.

Come una funzione anonima (utilizzare come o('yourstring'))

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

Immagino che questa funzione sia piuttosto autoesplicativa poiché si legge come una pubblicità su un giornale.

Versione precedente (29 byte):

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

L'input deve essere presentato tra i 'segni, ad es 'Potato'.


4

Brachylog , 3 byte

ḷ⊆Ạ

Provalo online!

Il predicato ha esito positivo se l'input soddisfa i requisiti delineati e in caso contrario, stampa true.o false.se eseguito come programma.

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

La prima versione che mi è venuta in mente, senza fare esplicito riferimento all'alfabeto:

Brachylog , 4 byte

ḷ≠.o

Provalo online!

        The input,
ḷ       lowercased,
 ≠      in which every character is distinct,
  .     is the output variable,
   o    which sorted,
        is still the output variable.

3

J, 21 caratteri

Questo è troppo lungo. L'argomento deve avere un rango 1, ovvero deve essere una stringa o un vettore.

*/@(<=~.;/:~)@tolower
  • tolower y- yin minuscolo.
  • /:~ y- yin ordine lessicale.
  • ~. y- il nocciolo di y, cioè ycon i duplicati rimossi.
  • x ; y- xe ymesso in scatole e poi concatenato.
  • < y- ymesso in una scatola.
  • x = y- x confrontato con l'elemento y.
  • (< y) = (~. y) ; (/:~ y)- un vettore che indica se yè uguale al suo nub e se stesso ordinato.
  • */ y- il prodotto degli articoli di y, o il suo logico e se gli articoli sono booleani.
  • */ (< y) = (~. y) ; (/:~ y)- un valore booleano che indica la proprietà desiderata per le lettere minuscole y.

3

Julia, 44 byte

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

Ciò crea una funzione anonima che accetta un singolo argomento s, lo converte in minuscolo e lo confronta con la versione ordinata univoca della stringa. Restituisce un valore booleano, ovvero trueo false. Se vuoi provarlo, assegnalo come f=s->...e poi chiama f("PuZ"), ecc.


Amen a quello, @flawr. Grazie per il supporto.
Alex A.

3

Pure Bash 4.x, 37

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

Input preso come parametro della riga di comando. Secondo la semantica della shell standard, il codice di uscita 0 significa vero (alfabetico) e il codice di uscita! = 0 significa falso (non alfabetico).

Printf crea il regex come nella soluzione di @ hsl . La stringa di input viene espansa in minuscolo e confrontata con regex.


Risposta precedente:

Bash + coreutils, 52

Soluzione semplice:

a=`fold -1<<<${1,,}`
cmp -s <(sort -u<<<"$a")<<<"$a"

Nota che questo richiede bash 4.x.
Mark Reed,

@MarkReed Sì. Notato.
Digital Trauma

3

C # 6, 18 + 82 76 = 94 byte

Richiede (18 byte):

using System.Linq;

Codice (76 byte):

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

C # 6 supporta lambda per definire una funzione, utile per giocare a golf.

Versione non C # 6:

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

Codice non golfato:

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

3

JavaScript (ES6) 54

Converti in maiuscolo, quindi in array e ordina. Se durante l'ordinamento due elementi sono nell'ordine sbagliato o uguale, restituisce 0 (falsa) altrimenti 1 (verità)

Modifica abbreviata thx a @Optimizer (ma comunque più che la soluzione implementata in @Tamas ES6 2: 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

Test nella 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"]


1
s=non sembra essere necessario ...
Optimizer

@Optimizer giusto, è stato un primo tentativo quando alla fine ho confrontato l'originale (maiuscolo) e l'ordinato
edc65

3

C (44 byte)

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

Provalo qui: http://ideone.com/q1LL3E

Pubblicare questo perché non posso ancora commentare, altrimenti sarebbe un suggerimento per migliorare la risposta C esistente perché ho completamente rubato l'idea insensibile al maiuscolo / minuscolo dalla risposta C esistente.

Restituisce 0 se la stringa non è ordinata e un valore diverso da zero se ordinato.


3

Golang (65 byte)

Go non è una lingua amica del golf, inoltre, faccio schifo al golf ...

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

Eseguilo qui: http://play.golang.org/p/xXJX8GjDvr

modifica 106-> 102

modifica 102-> 96

modifica 96-> 91

modifica 91-> 87

modifica 87-> 65

Ho battuto la versione java, posso smettere per oggi


3

Java 8 - 90 89 87 85 caratteri

L'idea qui è di usare una funzione 'riduci' che tiene traccia dell'ultimo carattere e "si arrende" quando rileva che la sequenza non è strettamente ascendente.

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

esempio:

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"));

produzione:

99
-1
122
122
122
-1

3

Perl 6, 35 byte

{my@c=.uc.comb;@c eq@c.sort.unique}

Questo produce un blocco richiamabile; se potessi solo supporre che $_sia già impostato sulla parola desiderata, potrei eliminare le parentesi graffe circostanti e perdere altri due byte, ma probabilmente l'unico modo ragionevole per fare questo presupposto sarebbe eseguirlo -ne alimentare la parola come input standard , che aggiungerebbe subito i due byte.


Certo che lo fa. .uc.combnon riorganizza nulla, quindi se la matrice maiuscola e combinata è uguale alla matrice maiuscola e combinata ordinata , significa che è iniziata nell'ordine ordinato.
Mark Reed,

giusto, sta controllando la dimensione dell'intersezione, che ignora l'ordine. Ok, aggiornato.
Mark Reed,

3

R , 37 byte

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

Provalo online!

La pubblicazione poiché è sostanzialmente diversa e più breve di della risposta R Michal .

Converte le lettere in punti di codice ASCII con utf8ToInt, quindi prende il modulo 32 in modo che le lettere inferiore e superiore vengano convertite negli stessi numeri 1 ... 26. Calcola le differenze a coppie e verifica che siano tutte positive.


2

Perl, 27

regexp di @ hsl compilato dinamicamente.

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

Inoltre possiamo fare una corrispondenza inversa: convertire l'input in un regexp: PuZ=> .*p.*u.*z.*e quindi abbinare questo a una stringa di lettere in ordine alfabetico. Risultato - anche 27 caratteri.

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

2

k (6 byte)

&/>':_

& restituisce vero se entrambi gli arg sono veri

/modifica &per applicare "sopra" un elenco, come una piega in linguaggi funzionali

> più grande di

':modifica >per applicare "ogni precedente", quindi restituisce un vettore di booleani indicando quali elementi sono maggiori del loro predecessore

_ lo rende argomento in minuscolo

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

( 0bsignifica booleano falso)

q (13 byte)

all(>':)lower

q è solo zucchero sintattico su k. allè definito come &/, e inferiore è_


4
Puoi spiegare come funziona?
flawr

Sembra quasi di tradire altre lingue ... Chi ha bisogno di nomi di funzioni, parentesi e punti e virgola? :)
Sanchises

@sanchises k ha tutte queste cose e funzionano più o meno allo stesso modo dei linguaggi in stile C. È solo che questo problema sembra essere esprimibile come una singola istruzione.
mollmerx


2

VBA (161 byte)

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  

Confronta il valore ASCII con la lettera precedente in minuscolo, restituisce 0 (falso) quando il suo valore è più piccolo / uguale ed esce dalla funzione


2

Python 2 , 43 byte

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

Provalo online!

Inserisce i <simboli tra tutte le lettere (convertite in lettere minuscole), quindi evals. Gli operatori di confronto concatenati di Python sono perfettamente felici di valutare il tutto come un'unica grande espressione booleana.


1

Erlang, 51

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

Utilizza un set ordinato (analogo a java.util.TreeSet ) per ordinare i personaggi e scartare eventuali duplicati. Il nuovo elenco viene quindi confrontato con la stringa di input.

Funzione di test:

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

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

Abbastanza semplice qui. Converti tutto in basso e confrontalo con il carattere precedente.

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.