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


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быть истинное значение?
MayorMonty

Нет, алфавит начинается с aи заканчивается на z.
Flawr

У вас должно быть несколько тестов, которые не в алфавитном порядке
Джо Кинг

1
@ Шучу, я добавил немного.
flawr

Ответы:


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

Regex (любой вкус), 55 байт

Некоторые люди не считают regex языком программирования, но он использовался раньше, и он не является самым коротким.

^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-буквенных слов в алфавитном порядке.

[«abhors», «почти», «начинается», «начальник», «бижутерия», «биопсия», «шимпанзе», «чинос», «ситец», «призрак»]


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 Я забыл про сетчатку. Благодарность!
NinjaBearMonkey

@ MartinBüttner Согласно META ( meta.codegolf.stackexchange.com/questions/2028/… ) регулярные выражения можно «рассматривать» как язык программирования.
Исмаэль Мигель

@IsmaelMiguel, я знаю. И на самом деле это определение было специально выбрано, чтобы убедиться, что оно не исключает регулярное выражение. Но некоторые люди все еще регулярно жалуются, потому что вы не можете использовать регулярные выражения, как любой другой язык.
Мартин Эндер

@ MartinBüttner Те, кто жалуется, могут пойти в место под названием META и найти его. Почему никто не посещает такое красивое место, полное вопросов, которые решают большинство проблем?
Исмаэль Мигель

19

Python 3, 44 байта

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

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


Можете ли вы объяснить, что *s,=...делает?
flawr

@flawr Это называется «помеченное назначение». В этом коде он просто преобразует правую сторону в список. Это так же, как s=list(input().lower()).
Якуб

1
@flawr Как говорит Якуб, здесь это просто преобразование ввода в список символов. В общем , это специальный синтаксис присваивания , который позволяет делать такие вещи , как x,*y = [1, 2, 3, 4], который сопоставляет 1 до xи [2, 3, 4]до y.
Sp3000

@ mbomb007 *s,= is 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
? ){:-<'`'/ ^^

(Изменение в стрелках и зеркалах справа)

фактически дает неверные результаты, потому что интерпретатор> <> использует defaultdict Python. В результате, проходя через пустое пространство в конце второй строки, 0 неявно помещаются в пустые пространства, когда> <> пытается получить доступ к ячейке. Это затем портит ?условный батут в начале той же строки, так как вновь помещенные 0 пропускаются, а не vв конце.


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

9

Haskell, 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), который я отфильтрую. Так что это может не работать с другими кодировками, очевидно.

РЕДАКТИРОВАТЬ: последняя версия всегда устанавливает 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

Ahelly хм, не учел это. Ваше предложение меняет исходную строку, хотя. Но как бы то ни было, это код гольф: D Также я не уверен насчет подсказки WChargin, так как d как глобальная переменная не будет частью функции.
Феликс Бытов

1
Почему бы не инициализировать dв forцикле, а не в собственном операторе? Таким образом, вы сохраните ;.
Джош

6

Руби, 33

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

Проверяет, совпадают ли отсортированные уникальные символы со всеми символами.


1
Думаю, что вы можете получить его немного короче сc==c.sort|c
гистократ

Ох, мне это нравится, это умно. Спасибо.
Британское

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

Кстати, контрольные примеры, которые в настоящее время находятся в OP, выполняются, если программа проверяет только уникальность, игнорируя порядок.


Я пока не могу писать комментарии, поэтому отвечу на некоторые замечания здесь:

@ edc65: Спасибо! Я попытался переписать его с помощью some(), но я не мог получить более короткое решение, потому что несмотря на то , похоже , это дало бы мне возможность избавиться от superflous переменной б, вам нужно ввести «возвращение» в два раза ( то же самое с 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 символа, представленная в виде обычной строки (с кавычками), является просто символьным атомом, а не реальной строкой, я соответствующим образом отформатировал ввод, чтобы весь ввод был реальным. (В приведенном выше примере я использовал 1$'a'.)


4

MATLAB, 29 27 байт

Теперь для одного лайнера, который даже имеет смысл вне код-гольфа.

Как анонимная функция (использовать как o('yourstring'))

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

Я предполагаю, что эта функция довольно понятна, так как она читается как реклама в газете.

Предыдущая версия (29 байт):

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

Ввод должен быть представлен между 'отметками, например 'Potato'.


4

Брахилог , 3 байта

ḷ⊆Ạ

Попробуйте онлайн!

Предикат успешно выполняется, если входные данные соответствуют изложенным требованиям, и не выполняется, если он не выполняется, печатается true.или false.запускается как программа.

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

Первая версия, которую я придумал, явно не ссылаясь на алфавит:

Брахилог , 4 байта

ḷ≠.o

Попробуйте онлайн!

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

3

J, 21 символов

Это слишком долго. Аргумент должен иметь ранг 1, то есть он должен быть строкой или вектором.

*/@(<=~.;/:~)@tolower
  • tolower y- yв нижнем регистре.
  • /:~ y- yв лексическом порядке.
  • ~. y- yто есть yс удаленными дубликатами.
  • x ; y- xи yположить в коробки, а затем соединены.
  • < y- yположить в коробку.
  • x = y- x по сравнению с поэлементно y.
  • (< y) = (~. y) ; (/:~ y)- вектор, указывающий, yравен ли его кусок и сам отсортирован.
  • */ y- произведение предметов yили его логика, и если предметы логические.
  • */ (< y) = (~. y) ; (/:~ y)- логическое значение, указывающее желаемое свойство в нижнем регистре y.

3

Юлия, 44 байта

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

Это создает анонимную функцию, которая принимает один аргумент s, преобразует его в нижний регистр и сравнивает с уникальной отсортированной версией строки. Возвращает логическое значение, т.е.truefalse . Или . Если вы хотите проверить это, назначьте его как, f=s->...а затем позвоните f("PuZ")и т. Д.


Аминь, @flawr. Спасибо за поддержку.
Алекс А.

3

Pure Bash 4.x, 37

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

Ввод принимается как параметр командной строки. Согласно стандартной семантике оболочки, код выхода 0 означает истину (буквенный), а код выхода! = 0 означает ложь (не буквенный).

Printf создает регулярное выражение как в решении @ hsl . Входная строка раскрывается в нижний регистр и сравнивается с регулярным выражением.


Предыдущий ответ:

Баш + кореутилс, 52

Простое решение:

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

Обратите внимание, что для этого требуется bash 4.x.
Марк Рид

@MarkReed Да. Принято к сведению.
Цифровая травма

3

C # 6, 18 + 82 76 = 94 байта

Требуется (18 байт):

using System.Linq;

Код (76 байт):

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

C # 6 поддерживает лямбда-выражения для определения функции, которая полезна для игры в гольф.

Версия без C # 6:

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

Ungolfed код:

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

3

JavaScript (ES6) 54

Преобразовать в верхний регистр, затем в массив и сортировку. Если во время сортировки два элемента находятся в неправильном порядке или равны, верните 0 (ложно), иначе 1 (верно)

Редактировать Укороченный ТНХ к @Optimizer (но все еще больше , чем решение @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

Тест в консоли 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=Вроде не требуется ...
Оптимизатор

@ Оптимизатор правильно, это была первая попытка, когда я наконец сравнил оригинал (в верхнем регистре) и отсортированный
edc65

3

C (44 байта)

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

Проверьте это здесь: http://ideone.com/q1LL3E

Отправляя это, потому что я пока не могу комментировать, в противном случае было бы предложение улучшить существующий C-ответ, потому что я полностью украл нечувствительную к регистру идею из существующего C-ответа.

Возвращает 0, если строка не упорядочена, и ненулевое значение, если упорядочено.


3

Голанг (65 байт)

Го - это не дружелюбный язык для гольфа, я тоже сосу в гольф ...

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

Запустите его здесь: http://play.golang.org/p/xXJX8GjDvr

редактировать 106-> 102

редактировать 102-> 96

редактировать 96-> 91

редактировать 91-> 87

редактировать 87-> 65

Я бью Java-версию, я могу остановиться на сегодня


3

Java 8 - 90 89 87 85 символов

Идея здесь состоит в том, чтобы использовать функцию «уменьшить», которая отслеживает последний символ и «сдается», когда обнаруживает, что последовательность не является строго восходящей.

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

пример:

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

выход:

99
-1
122
122
122
-1

3

Perl 6, 35 байт

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

Это производит вызываемый блок; если бы я мог предположить, что $_уже установлено желаемое слово, я мог бы удалить окружающие фигурные скобки и потерять еще два байта, но, вероятно, единственный разумный способ сделать это предположение состоял бы в том, чтобы запустить его -nи передать слово в качестве стандартного ввода. , который добавил бы два байта назад.


Конечно, это так. .uc.combничего не переставляет, поэтому, если массив в верхнем и гребенном регистре равен отсортированному массиву в верхнем и гребенном, это означает, что он начинался в отсортированном порядке.
Марк Рид

Да, это проверка размера пересечения, который игнорирует порядок. Хорошо, обновлено.
Марк Рид

3

R , 37 байт

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

Попробуйте онлайн!

Регистрация, поскольку это существенно отличается и короче, чем ответ Михала R .

Преобразует буквы в кодовые точки ASCII с помощью utf8ToInt, а затем принимает модуль 32, чтобы нижние и верхние буквы были преобразованы в одинаковые числа 1 ... 26. Вычисляет попарные разности и проверяет, все ли они положительны.


2

Perl, 27

регулярное выражение @ hsl.

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

Также мы можем выполнить обратное сопоставление: преобразовать входные данные в регулярное выражение: PuZ=>, .*p.*u.*z.*а затем сопоставить его со строкой букв в алфавитном порядке. Результат - тоже 27 символов.

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

2

к (6 байт)

&/>':_

& возвращает true, если оба аргумента верны

/модифицирует, &чтобы применить "поверх" списка, как сгиб в функциональных языках

> больше чем

':модифицируется, >чтобы применять «каждый-предшествующий», поэтому возвращает вектор логических значений, указывающих, какие элементы больше, чем их предшественник

_ аргумент в нижнем регистре

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

( 0bозначает логическое значение false)

q (13 байт)

all(>':)lower

д просто синтаксический сахар на к. allопределяется как &/, а ниже_


4
Можете ли вы объяснить, как это работает?
flawr

Это похоже на обман на других языках ... Кому нужны имена функций, скобки и точки с запятой? :)
Sanchises

В @sanchises k есть все эти вещи, и они работают почти так же, как в языках стиля C. Просто эта проблема может быть выражена как одно утверждение.
Mollmerx


2

VBA (161 байт)

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  

Сравнивает значение ascii с предыдущей буквой в нижнем регистре, возвращает 0 (false), если его значение меньше / равно, и завершает работу


2

Python 2 , 43 байта

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

Попробуйте онлайн!

Помещает <символы между всеми буквами (преобразуются в нижний регистр) и затем evalотображает их. Цепные операторы сравнения Python с радостью оценивают все это как одно большое логическое выражение.


1

Эрланг, 51

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

Использует упорядоченный набор (аналогично java.util.TreeSet ) для сортировки символов и удаления любых дубликатов. Затем новый список сравнивается со строкой ввода.

Тестовая функция:

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

1

Ява, 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;}

Довольно просто здесь. Просто конвертируйте все в нижние и сравните каждый с предыдущим символом.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.