检查单词字母是否按字母顺序排列


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 APHP答案的评论。)
manatwork

字母会循环吗?应该za是一个真实的价值?
2015年

不,字母以开头a和结尾z
瑕疵的

您应该拥有一些按字母顺序排列的测试用例
Jo King

1
@JoKing我添加了一些。
flawr

Answers:


28

CJam,8个字节

lel_$_&=

这是挑战中所有示例的测试工具。这将返回01(在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个字节

有些人不认为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(不区分大小写)标志添加了一个字节。这是非常简单的,并且可能会更短地生成。

如果仅不允许使用正则表达式,则可以使用MartinBüttner建议的这个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 2015年

@MartinBüttner我忘记了视网膜。谢谢!
NinjaBearMonkey 2015年

@MartinBüttner根据META(meta.codegolf.stackexchange.com/questions/2028/…)可以将Regexe看作某种编程语言。
Ismael Miguel

@IsmaelMiguel我知道。实际上,该定义是专门为确保不排除正则表达式而选择的。但是有些人仍然经常抱怨,因为您不能像其他任何语言一样使用正则表达式。
Martin Ender'3

@MartinBüttner抱怨的人可以去一个叫做META的地方寻找它。为什么没有人会参观如此美丽的地方,那里充满了可以解决大多数问题的问题?
伊斯梅尔·米格尔

19

Python 3,44个字节

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

一种简单的方法-检查唯一性,检查排序。


你能解释一下*s,=...吗?
瑕疵的

@flawr这称为“已加星标分配”。在此代码中,它仅将右侧转换为列表。与相同s=list(input().lower())
2015年

1
正如Jakube所说,@ flawr只是将输入转换成字符列表。通常,这是一种特殊的分配语法,可让您执行诸如x,*y = [1, 2, 3, 4]x和分配为1的[2, 3, 4]操作y
Sp3000

@ mbomb007 *s,= list(s) ... 链接
Sp3000

您可以{*s}代替set(s)保存2个字节。
mbomb007 '01

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 defaultdict的> <>的解释器,实际上给出了错误的结果。发生的情况是,通过遍历第二行末尾的空白区域,当> <>尝试访问该单元格时,会将0隐式放置在空白区域中。然后,这会与?同一行开头的条件蹦床发生混乱,因为新放置的0会被跳过,而不是v在结尾处。


我觉得您可以通过仅从小写字母中减去32而不是为所有字母获取字母索引来节省一些字节
Aaron

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 2015年

通过将for循环替换为保存2 for(;(*s&=95)>d;d=*s++);。而且您可以初始化d1而不更改结果,从而节省了1个以上。 看到。
AShelly

1
我不确定这在代码高尔夫中是否被认为是合法的,但是d;f(char*s){d=32;for...}可以正常工作,d隐式声明为全局int(在GCC中,这是一个警告,“数据定义没有类型或存储类”,但没有错误)。这样可以节省两个字节。
wchargin'3

AShelly嗯,没有考虑这一点。您的建议虽然更改了原始字符串。但是无论如何,它是代码golf:D另外,我不确定WChargin的提示,因为d作为全局变量确实不是该函数的一部分。
菲利克斯·拜托

1
为什么不初始化dfor循环,而不是它自己的说法?这样,您就可以保存一个;
乔什(Josh)

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}

edc95提高到87:

支持他的评论:)

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

顺便说一句,如果程序仅检查唯一性而无视顺序,则满足OP中当前的测试用例。


我还不能发表评论,所以我在这里回答一些评论:

@ edc65:谢谢!我尝试使用重写它some(),但是我无法得到一个更短的解决方案,因为即使看起来它可以使我摆脱多余的b变量,您也需要两次键入“ return”(与相同reduce()),并且您不能只直接返回比较结果,因为与之比较后需要保存最后一个字符。

@ edc65:很好地使用了逗号运算符87!我将其编辑为答案,以提高可见性。


这是比我更好的主意。使用.some可能会更好(ES6使用52)
edc65 2015年

您可以删除之间的空间return!b保存字符。
ProgramFOX

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

同样,打得更多,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 toLowerfrom Data.Char代替lowercase
nimi

1
此外,您也可以删除参数lf,即f=g.lowercase(或者f=g.map toLower如果切换到toLower)。在g一个比较是不够的:g l=nub(sort l)==l
nimi 2015年

4

Wolfram Mathematica,49个 37字节

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

PS MartinerBüttner的较短解决方案:

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

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

1
@alephalpha太漂亮了!
马丁·恩德

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

Brachylog,3个字节

ḷ⊆Ạ

在线尝试!

如果输入满足概述的要求,则谓词成功;否则,打印true.false.作为程序运行,则谓词失败。

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

我想出的第一个版本没有明确引用字母:

Brachylog,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个字符

这太长了。参数必须具有rank 1,即它必须是字符串或向量。

*/@(<=~.;/:~)@tolower
  • tolower yy小写。
  • /:~ yy以词法顺序。
  • ~. y–的小节y,即y删除重复项。
  • x ; y- xy投入盒,然后再连接。
  • < yy放进盒子里。
  • x = yx 与进行逐元素比较y
  • (< y) = (~. y) ; (/:~ y)–指示if y是否等于其nub并对其进行排序的向量。
  • */ y–的各项的乘积y或逻辑,以及各项是否为布尔值。
  • */ (< y) = (~. y) ; (/:~ y)–一个布尔值,指示小写字母的所需属性y

3

朱莉娅,44字节

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

这将创建一个使用单个参数的匿名函数s,将其转换为小写字母,然后将其与字符串的唯一排序版本进行比较。它返回一个布尔值,即trueor false。如果您想对其进行测试,请像分配它f=s->...,然后调用f("PuZ"),等等。


恭喜,@ flawr。感谢您的支持。
Alex A.

3

Pure Bash 4.x,37

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

输入作为命令行参数。根据标准Shell语义,退出代码0表示true(字母),退出代码!= 0表示false(不是字母)。

printf像@hsl的solution一样创建正则表达式。输入字符串将扩展为小写并与正则表达式进行比较。


先前的答案:

Bash + coreutils,52岁

简单的解决方案:

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

请注意,这需要bash4.x。
Mark Reed

@MarkReed是的。注意。
Digital Trauma'3

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支持lambda定义函数,这对于打高尔夫球很有用。

非C#6版本:

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

取消程式码:

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

3

JavaScript(ES6)54

转换为大写,然后转换为数组并排序。如果在排序过程中两个元素的顺序错误或相等,则返回0(虚假),否则返回1(真实)

编辑缩短到@Optimizer的thx(但比ES6中实现的@Tamas解决方案多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=似乎不需要...
Optimizer

@Optimizer对,这是第一次尝试,最后我比较了原始(大写)和已排序
edc65,2015年

3

C(44字节)

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

在此处进行测试:http : //ideone.com/q1LL3E

发布此消息是因为我目前无法发表评论,否则建议改进现有的C答案,因为我从现有的C答案中完全窃取了不区分大小写的想法。

如果未排序字符串,则返回0;如果未排序,则返回非零值。



3

爪哇8 - 90 89 87 85个字符

这里的想法是使用“减少”功能来跟踪最后一个字符,并在检测到序列未严格递增时“放弃”。

打高尔夫球:

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

松散:

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不会重新排列任何内容,因此,如果大写和梳理数组等于已排序的大写和梳理数组,则意味着它以排序顺序开始。
Mark Reed

正确,它正在检查相交的大小,而忽略了顺序。好的,已更新。
Mark Reed

3

R,37个字节

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

在线尝试!

发布,因为这与Michal的R Answer实质上不同且较短。

用转换字母为ASCII码点utf8ToInt,然后取32为模,以便将低位和高位字母转换为相同的数字1 ... 26。计算成对差异,并检查它们是否均为正。


2

Perl,27岁

@hsl的regexp动态生成。

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

我们还可以进行反向匹配:将输入转换为regexp:PuZ=> .*p.*u.*z.*,然后将其匹配到字母顺序的字母字符串。结果-也是27个字符。

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

2

k(6个字节)

&/>':_

& 如果两个参数都为true,则返回true

/修改&以将列表“应用于”列表,例如功能语言中的折叠

> 比...更棒

':修改>以应用“ each-prior”,因此返回一个布尔向量,指示哪些元素大于其前任元素

_ 使参数变小写

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

0b表示布尔值false)

q(13个字节)

all(>':)lower

q只是k上的语法糖。all定义为&/,而lower为_


4
您能解释一下这是如何工作的吗?
瑕疵的

这几乎就像在欺骗其他语言一样……谁需要函数名称,括号和分号?:)
Sanchises

@sanchises k具有所有这些功能,它们的工作方式几乎与C风格语言相同。只是这个问题恰好可以表达为单个语句。
mollmerx 2015年


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(假),然后退出函数


2

Python 2,43个字节

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

在线尝试!

<符号放在所有字母之间(转换为小写字母),然后eval对其进行处理。Python的链式比较运算符非常乐意将整个事件作为一个大布尔表达式进行评估。


1

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

这里很简单。只需将所有内容转换为较低的内容,然后将其与上一个字符进行比较即可。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.