Перевірте, чи букви слова в алфавітному порядку


37

Напишіть функцію / програму, яка приймає рядок малих та малих літер [A-Za-z] як вхідних даних, які перевіряють, чи є букви, що виникають, унікальними та в алфавітному порядку (ігноруючи малі та великі регістри) чи ні. Вихід повинен бути правдивим, якщо вони унікальні, в алфавітному порядку і хибними, якщо ні.

Ось кілька тестів

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

Якщо ви хочете, запустіть програму на всіх словах списку слів, як цей і опублікуйте цікаві =).

Оцінка

Найменша кількість виграних байтів.


3
Слабкі тестові випадки. (Див мій коментар про Richard A «s PHP відповідь .)
manatwork

Чи петля алфавіту? Чи має zaбути правдиве значення?
МерМонті,

Ні, алфавіт починається з aі закінчується z.
недолік

У вас повинні бути кілька тестових випадків, які не в алфавітному порядку
Jo King

1
@JoKing Я додав деякі.
недолік

Відповіді:


28

CJam, 8 байт

lel_$_&=

Ось тестовий джгут для всіх прикладів виклику. Це повертає 0або1 (що є фальшивим і правдивим, відповідно, у CJam).

І ось тут сценарій для фільтра списку слів у запитанні (потрібно кілька секунд для запуску). Вам доведеться скопіювати список слів у поле введення вручну, тому що це занадто довго для постійної посилання.

Пояснення

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

Регекс (будь-який аромат), 55 байт

Деякі люди не вважають регулярний вираз мовою програмування, але він використовувався раніше, і він не близький до того, щоб бути найкоротшим.

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

Я додав один байт для iпрапора (нечутливий до регістру). Це дуже просто і може бути коротшим, щоб генеруватися на льоту.

Якщо тільки регулярний вираз не дозволений, ви можете скористатися цією 56- байтною програмою Retina, запропонованою Мартіном Бюттнером:

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

Запустивши це у списку слів, пов'язаних вище, вийшло 10 6-літерних слів в алфавітному порядку.

["недоброзичливці", "майже", "починається", "побратим", "біжукс", "біопсія", "шимпанзе", "чінос", "синт", "привид"]


2
Ви можете використовувати Retina замість ES6, якщо хтось скаржиться, що регулярний вираз не є мовою: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 Я забув про Retina. Спасибі!
NinjaBearMonkey

@ MartinBüttner Відповідно до META ( meta.codegolf.stackexchange.com/questions/2028/… ) Regexes можна дещо «сприймати» як мову програмування.
Ісмаїл Мігель

@IsmaelMiguel Я знаю. Насправді це визначення було обрано спеціально, щоб переконатися, що воно не виключає регулярного вираження. Але деякі люди все ще регулярно скаржаться, тому що ви не можете використовувати регулярний вираз, як будь-яка інша мова.
Мартін Ендер

@ MartinBüttner Ті, хто скаржиться, можуть зайти до місця під назвою META і шукати його. Чому ніхто не відвідує таке прекрасне місце, повне питань, які вирішують більшість питань?
Ісмаїл Мігель

19

Python 3, 44 байти

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

Простий підхід - перевірити унікальність, перевірити впорядкованість.


Чи можете ви пояснити, що *s,=...робить?
недолік

@flawr Це називається "призначення зірки". У цьому коді він просто перетворює праву частину в список. Це те саме, що s=list(input().lower()).
Якубе

1
@flawr Як каже Якубе, тут це просто перетворення вхідних даних у список символів. Загалом , це спеціальний синтаксис присвоювання , який дозволяє робити такі речі , як x,*y = [1, 2, 3, 4], який зіставляє 1 до xі [2, 3, 4]до y.
Sp3000

@ mbomb007 *s,= - це list(s) ... посилання
Sp3000

Ви можете зробити {*s}замість того, set(s)щоб зберегти 2 байти.
mbomb007

12

> <> , 52 42 39 байт

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

Цей тип запитань - один з небагатьох типів, з яким <<> досить зручно, оскільки нам потрібно займатися лише одним знаком за один раз.

Пояснення

Не заблукайте! Тут багато обгортки.

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

Попереднє рішення, 42 байти

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

Цікавим є те, що, незважаючи на те, що вони мають однаковий функціонал, альтернатива

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

(Зміна в стрілках і дзеркалах в крайній правій частині)

насправді дає невірні результати, завдяки інтерпретатору, що використовує програму Python за замовчуванням. Що трапляється, це те, що, проходячи через порожній пробіл в кінці другого ряду, 0s неявно поміщаються в порожні пробіли, коли> <> намагається отримати доступ до комірки. Потім це псується із ?умовним батутом на початку того ж ряду, оскільки щойно розміщені 0 пропускаються, а не vв кінці.


Я відчуваю, що ти міг би зберегти кілька байт, лише віднісши 32 з малих літер, а не отримавши алфавітний індекс для всіх літер
Аарон,

9

Хаскелл, 52 байти

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

Використання: (and.(zipWith(>)=<<tail).map toLower) "abcd"які виходи True.


9

C, 67 65 57 54 (52) символів

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

трохи коротше:

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

і навіть коротше:

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

Ось невеликий тест: http://ideone.com/ZHd0xl

Після останніх пропозицій тут ще дві коротші версії:

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

Також цей код покладається на той факт, що в ASCII малі та великі регістри відрізняються лише 5-м бітом (32), який я фільтрую. Так що, очевидно, це не може працювати з іншими кодуваннями.

EDIT: Остання версія завжди встановлює 5-й біт як |32менший &~32.


Гарне використання знань про домен для вирішення проблеми чутливості до справи.
RomSteady

Збережіть 2, замінивши цикл for на for(;(*s&=95)>d;d=*s++);. І ви можете форматувати dдо 1без зміни результату, заощадивши більше 1. Побачити.
AShelly

1
Я не впевнений, чи вважається це законним у коді гольф, але d;f(char*s){d=32;for...}працює, dнеявно заявляючи як глобальний int (що в GCC є попередженням - "визначення даних не має типу або класу зберігання" - але не є помилкою). Це економить два байти.
wchargin

AShelly гм, не врахував це. Однак ваша пропозиція змінює початковий рядок. Але що б там не було, це код гольфу: D Також я не впевнений у підказці WChargin, оскільки d як глобальна змінна насправді не буде частиною функції.
Фелікс Байтов

1
Чому б не ініціалізуватись dу forциклі, а не у власному викладі? Таким чином ви заощадите ;.
Джош

6

Рубі, 33

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

Перевіряє, чи відсортовані унікальні символи однакові, як і всі символи.


1
Подумайте, ви можете зробити це трохи коротшеc==c.sort|c
гістократ

Ой, мені це подобається, це розумно. Спасибі.
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}

Покращено до 87 від edc95:

підтвердити його коментар :)

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

До речі, тестові випадки, які зараз є в ОП, виконуються, якщо програма лише перевіряє унікальність, не зважаючи на порядок.


Я поки не можу писати коментарі, тому відповім на деякі зауваження тут:

@ edc65: Дякую! Я спробував переписати це за допомогою some(), але не зміг отримати коротше рішення, тому що, хоч це виглядає так, що це дозволить мені позбутися від чудової змінної b, вам потрібно набрати "return" двічі (те самеreduce() ), і ви не може просто повернути результат порівняння безпосередньо, оскільки останній символ потрібно зберегти після порівняння з ним.

@ edc65: Це гарне використання кома оператора для 87! Я відредагував це у свою відповідь для більшої наочності.


Це краща ідея, ніж моя. Використання .some може бути ще кращим (52 з ES6)
edc65

Ви можете видалити пробіл між returnі !bзберегти знак.
ProgramFOX

Як це, просто дбайливий білий простір, 96:function i(s){b=0;l='';s.toUpperCase().split('').forEach(function(c){if(c<=l)b=1;l=c});return!b}
edc65

Те саме, більше гольфу, 92:function i(s){s.toUpperCase(b=0).split(l='').forEach(function(c){if(c<=l)b=1;l=c});return!b}
edc65

1
Використовуючи деякий (або кожен, той самий бал), 87:function i(s){return!s.toUpperCase().split(l='').some(function(c){return(u=l,l=c)<=u})}
edc65

4

Haskell, 90 байт

Постачає функцію f :: String -> Bool

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

Використання (якщо при цьому збережено як golf.hs). ...використовується для заміни ghciбагатослівного завантаження повідомлень.

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

Якщо у когось lowercaseметод коротший, import Distribution.Simple.Utilsто прокоментуйте його.


1
Використання map toLowerз Data.Charзамістьlowercase
Ними

1
Також: ви можете видалити параметр lу f, тобто f=g.lowercase(або f=g.map toLowerякщо ви переходите на toLower). В gодне порівняння досить: g l=nub(sort l)==l.
німі


4

J, 17 байт

Перевіряє, чи відсортований /:~рядок -:з малих літер дорівнює рядку нуля малих літер ~..

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

Як і в J, один рядковий "рядок", представлений як звичайний рядок (з лапками), - це просто атом символів, а не реальна рядок, я правильно відформатував вхід, щоб весь вхід був справжнім рядком. (У наведеному вище прикладі 1$'a'.)


4

MATLAB, 29 27 bytes

Now for a one-liner which even makes sense outside of code-golf.

As an anonymous function (use as o('yourstring'))

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

I guess this function is pretty self-explanatory since it reads like a newspaper ad.

Previous version (29 bytes):

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

Input must be presented between ' marks, e.g. 'Potato'.


4

Brachylog, 3 bytes

ḷ⊆Ạ

Try it online!

The predicate succeeds if the input meets the requirements outlined and fails if it does not, printing true. or false. if run as a program.

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

The first version I came up with, not explicitly referencing the alphabet:

Brachylog, 4 bytes

ḷ≠.o

Try it 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 characters

This is too long. The argument must have rank 1, i.e. it must be a string or vector.

*/@(<=~.;/:~)@tolower
  • tolower yy in lower case.
  • /:~ yy in lexical order.
  • ~. y – the nub of y, that is, y with duplicates removed.
  • x ; yx and y put into boxes and then concatenated.
  • < yy put into a box.
  • x = yx compared element-wise with y.
  • (< y) = (~. y) ; (/:~ y) – a vector indicating if y is equal to its nub and itself sorted.
  • */ y – the product of the items of y, or its logical and if the items are booleans.
  • */ (< y) = (~. y) ; (/:~ y) – a boolean indicating the desired property for lowercase y.

3

Julia, 44 bytes

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

This creates an anonymous function that takes a single argument s, converts it to lower case, and compares it to the unique sorted version of the string. It returns a boolean, i.e. true or false. If you want to test it out, assign it like f=s->... and then call f("PuZ"), etc.


Amen to that, @flawr. Thanks for the support.
Alex A.

3

Pure Bash 4.x, 37

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

Input taken as a command-line parameter. As per standard shell semantics, exit code 0 means true (alphabetic) and exit code != 0 means false (not alphabetic).

The printf creates the regex as in @hsl's solution. The input string is expanded to lowercase and compared against the regex.


Previous answer:

Bash + coreutils, 52

Straightforward solution:

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

Note that this requires bash 4.x.
Mark Reed

@MarkReed Yes. Noted.
Digital Trauma

3

C# 6, 18 + 82 76 = 94 bytes

Requires (18 bytes):

using System.Linq;

Code (76 bytes):

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

C# 6 supports lambdas to define a function, which is useful for golfing.

Non-C# 6 version:

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

Ungolfed code:

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

3

JavaScript (ES6) 54

Convert to uppercase, then to array and sort. If during sort two element are in the wrong order or equal, return 0 (falsy) else 1 (truthy)

Edit Shortened thx to @Optimizer (but still 2 more than the @Tamas solution implemented in 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

Test in Firefox / FireBug console

;['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= does not seem to be required...
Optimizer

@Optimizer right, it was a first try when at last i compared the original (uppercased) and the sorted
edc65

3

C (44 bytes)

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

Test it here: http://ideone.com/q1LL3E

Posting this because I can't comment yet, otherwise it would be a suggestion to improve the existing C answer because I completely stole the case-insensitive idea from the existing C answer.

Returns 0 if the string is not ordered, and a non-zero value if ordered.



3

Java 8 - 90 89 87 85 chars

The idea here is to use a 'reduce' function that tracks the last char and "gives up" when it detects the sequence is not strictly ascending.

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

example:

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

output:

99
-1
122
122
122
-1

3

Perl 6, 35 bytes

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

This produces a callable block; if I could just assume that $_ is already set to the desired word, I could delete the surrounding curly braces and lose two more bytes, but probably the only reasonable way to make that assumption would be to run it with -n and feed the word as standard input, which would add the two bytes right back.


Sure it does. .uc.comb doesn't rearrange anything, so if the uppercased and combed array is equal to the sorted uppercased and combed array, that means it started out in sorted order.
Mark Reed

right, it's checking the size of the intersection, which ignores order. Ok, updated.
Mark Reed

3

R, 37 bytes

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

Try it online!

Posting since this is substantially different and shorter than Michal's R answer.

Converts the letters to ASCII codepoints with utf8ToInt, then takes modulo 32 so that lower and upper letters are converted to the same numbers 1...26. Computes the pairwise differences, and checks that they are all positive.


2

Perl, 27

@hsl's regexp dynamically build.

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

Also we can do a reverse match: convert the input into a regexp: PuZ => .*p.*u.*z.* and then match this to a string of letters in alphabetical order. Result - also 27 characters.

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

2

k (6 bytes)

&/>':_

& returns true if both args are true

/ modifies & to apply "over" a list, like a fold in functional languages

> greater than

': modifies > to apply "each-prior", so returns a vector of booleans stating which elements are greater than their predecessor

_ makes it argument lower case

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

(0b means boolean false)

q (13 bytes)

all(>':)lower

q is just syntactic sugar on k. all is defined as &/, and lower is _


4
Can you explain how this works?
flawr

This almost feels like cheating on other languages... Who needs function names, parentheses and semicolons? :)
Sanchises

@sanchises k has all of those things and they work pretty much the same way as in C style languages. It's just that this problem happens to be expressible as a single statement.
mollmerx


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  

Compares ascii value with previous letter in lowercase, return 0 (false) when its value is smaller / equal and exit function


2

Python 2, 43 bytes

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

Try it online!

Puts < symbols between all the letters (converted to lowercase), and then evals it. Python's chained comparison operators are perfectly happy to evaluate the whole thing as one big boolean expression.


1

Erlang, 51

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

Uses an ordered set (analogous to java.util.TreeSet) to sort the characters and discard any duplicates. The new list is then compared with the input string.

Test Function:

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

Pretty straightforward here. Just convert all to lower and compare each to the previous character.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.