计数连续字符


24

给定一个仅包含字母的字符串,输出该单词包含的连续字母最长的长度,顺序无关紧要。示例算法可以对单词进行排序,删除重复项,然后输出最长运行时间的长度。

测试用例

watch -> 1
stars -> 3
antidisestablishmentarianism -> 3
backdoor -> 4
a -> 1
tutorials -> 4

例如,antidisestablishmentarianism包含字母abdehilmnstr。最长的行程是lmnrst,长度均为3。

笔记

您可以将所有小写字母,所有大写字母或大小写混合的字母作为输入,但是大小写无法对有关该单词的信息进行编码(即,您不能将首n字母大写,n即最长的长度)。

这是,因此最短答案以字节为单位。


@ H.PWiz,我猜这是一个错字,应该是rst-唯一化,排序并获得最长的连续运行。我们可以将输入作为字符数组吗?
毛茸茸的

@Shaggy是的,当然,我没有包含它,因为我认为它是默认设置
Stephen

“ a”与“ z”相邻吗?“斑马”应得分2还是3?
乔纳森·艾伦

(...根据您的示例算法判断,我猜是“否”和“ 2”)
乔纳森·艾伦

@乔纳森·艾伦,你是对的
斯蒂芬

Answers:


10

果冻 10 9 8 7  6 个字节

OṬṣ0ZL

在线尝试!

9是使用Sok的方法ṢQẆẇƇØaṪL

怎么样?

OṬṣ0ZL - Link: list of (single-case) characters  e.g.  codegolf
O      - ordinal (vectorises)           [99,111,100,101,103,111,108,102]
 Ṭ     - untruth (1s at those indices)  [0,0,0,...,1,1,1,1,1,0,0,0,0,1,0,0,1]
       -                                 ^         ^       ^         ^     ^
       -                   i.e. indices: 1        99     103       108   111
   0   - literal zero
  ṣ    - split at                       [[],[],[],...,[1,1,1,1,1],[],[],[],[1],[],[1]]
    Z  - transpose                      [[1,1,1],[1],[1],[1],[1]]
     L - length                         5

8

[R44 43字节

适用于小写字符数组。编辑:将其从测试True值更改为乘以一个字节的T / F。

function(x,r=rle(letters%in%x))max(r$l*r$v)

在线尝试!

对提供的字符中的字母进行游程编码,然后返回true的最大值。


正在使用utf8ToInt研究类似的rle解决方案,但是采用字符串数组要聪明得多。+1
JayCe

@JayCe以相同的方式开始,但后来意识到%in%的字母检查可一举完成排序,唯一和差异步骤
MickyT

7

APL(Dyalog Classic)10 9字节

-1个字节感谢H.PWiz

≢⍉↑⊆⍨⎕a∊⍞

在线尝试!

输入一个字符串

⎕a 是大写英文字母

⎕a∊⍞ 布尔长度为26的向量-字符串中出现哪些字母?

⊆⍨ 连续1的形式向量

≢⍉↑ 混合成矩阵,转置并返回其高度-有效地,找到最长向量1s的长度


1
⌈/≢¨ -> ≢⍉↑
H.PWiz

6

Perl 6,41个字节

{max values bag .ords.sort.squish Z-0..*}

测试一下

展开:

{  # bare block lambda with implicit param $_

  max       # find the max
    values  # get the values from the following Bag (repeat counts)
      bag   # find the repeats

          .ords.sort.squish # get the unique ordinals (method call on $_)
        Z-                  # zip subtract with
          0 .. *            # Range starting with 0
}

给定 'stars'.ords.sort.squish Z-0..*将返回(97,113,113,113)



6

JavaScript(Node.js),51字节

输入字符串的大小写无关紧要。

s=>(g=_=>s&&1+g(s&=s*2))(Buffer(s).map(c=>s|=1<<c))

在线尝试!

怎么样?

我们首先使用以下命令将输入​​字符串转换为遇到的字母的位掩码:

Buffer(s).map(c => s |= 1 << c)

按位移位使用隐式模32处理。

例:

"feedback" --> 100001111110
               kjihgfedcba-

然后,通过重复将其与自身左移的副本进行“与”操作,直到位全部被清除,从而“减少”位掩码中连续1的运行:

0100001111110 AND 1000011111100 --> 0000001111100
0000001111100 AND 0000011111000 --> 0000001111000
0000001111000 AND 0000011110000 --> 0000001110000
0000001110000 AND 0000011100000 --> 0000001100000
0000001100000 AND 0000011000000 --> 0000001000000
0000001000000 AND 0000010000000 --> 0000000000000

字母顺序的连续字母数是上述过程的迭代数。因此,递归函数:

g = _ => s && 1 + g(s &= s * 2)

5

Pyth,9个字节

le}#G.:S{

假定输入为小写字符串。在此处在线尝试,或在此处一次验证所有测试用例。

le}#G.:S{Q   Q=eval(input()), G=lowercase alphabet. Trailing Q inferred.

        {Q   Deduplicate input string
       S     Sort it
     .:      Take all substrings (these are generated in length order)
  }#G        Filter out those that aren't found in the alphabet
le           Find the length of the last remaining element

使用子串按长度排序的事实的好方法!
乔纳森·艾伦

效率将大大降低,但是您可以y代替使用.:
FryAmTheEggman

5

MATL,10字节

2Y2imY'*X>

输入为小写。

在线尝试!要么验证所有测试用例

这混合使用 @Sundar(旧)和@ngn方法。

说明

以输入'tutorial'为例。

2Y2   % Push predefind literal 'abcdefghijklmnopqrstuvwxyz'
      % STACK: 'abcdefghijklmnopqrstuvwxyz'
i     % Push input
      % STACK: 'abcdefghijklmnopqrstuvwxyz', 'tutorials'
m     % Ismember: true for letters present in the input
      % STACK: [1 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 0 0 0]
Y'    % Run-length encoding
      % STACK: [1 0 1 0 1 0 1 0 1 0], [1 7 1 2 1 2 1 2 4 5]
*     % Multiply, element-wise
      % STACK: [1 0 1 0 1 0 1 0 4 0]
X>    % Maximum. Implicitly display
      % STACK: 4


5

05AB1E,6个字节

Œ...éæ

êæAÃθg

在线尝试!

还有6个字节

再次节省了2个字节,这要归功于Adnan:使用ASå相反êÇ¥Θ,因此也无需在末尾增加最大值。请参阅修订历史记录以比较这两种方法的优点。

ASåγOà

在线尝试!

这些如何运作

我喜欢这样的挑战,它会导致多种不同的方法。

êæAÃθg | Full program.
ê      | Push a sorted and without duplicates version of the input.
 æ     | Powerser.
  AÃ   | Keep those that also occur in the lowercase alphabet.
    θg | Take the length of the last one. θ and ` can be used interchangeably.
-------+-------------------------------------------------------------------------------
ASåγOà | Full program.
A      | Push the lowercase alphabet.
 S     | Listify it (i.e. convert it to a sequence of characters).
  å    | Replace each char in the alphabet by 1 if its in the input, else by 0.
   γ   | Split into chunks of equal adjacent elements.
    O  | Sum each part.
     à | Extract the maximum of this list. Again, à and Z can be used interchangeably.

第一个程序可以打高尔夫球,êæAÃ`g第二个程序可以打高尔夫球ASåγOZ
阿德南'18

@Adnan谢谢,更新!我喜欢这个ASå把戏。
Xcoder先生18年

4

TSQL(Microsoft SQL Server),206字节

WITH C AS (SELECT 1p,SUBSTRING(@,1,1)c UNION ALL SELECT p+1,SUBSTRING(@,p+1,1)FROM C WHERE p<LEN(@)),R AS(SELECT c d,1r FROM C UNION ALL SELECT c,r+1FROM R JOIN c ON ASCII(d)+1=ASCII(c))SELECT MAX(r)FROM R

对于输入,DECLARE在代码之前使用以下语句:

DECLARE @ varchar(200) = 'propinquities';

预期输入都是相同的大小写(大小写无关紧要,但是混合大小写不起作用)。

取消高尔夫:

DECLARE @data varchar(200) = 'propinquities'

;WITH CTE AS (
    SELECT
        1 as CharacterPosition,
        SUBSTRING(@data,1,1) as Character
    UNION ALL
    SELECT
        CharacterPosition + 1,
        SUBSTRING(@data,CharacterPosition + 1,1)
    FROM
        CTE
    WHERE CharacterPosition < LEN(@data)
), Runs AS
(
    SELECT Character, 1 rc
    FROM CTE
    UNION ALL
    SELECT b.Character, rc + 1
    FROM Runs r
    JOIN CTE b ON ASCII(r.Character) + 1 = ASCII(b.Character)
)
SELECT max(rc)
from runs

说明:

将字符串中的每个字符拆分为一个行(改编自/programming//a/27623321/1474939)。CTE

然后,通过转换为Runscte中的ASCII码来查找连续字母的序列。

最后,它选择最大的运行并在select语句中返回报告。


好的答案,很好地使用了CTE。不知道这是否会帮助或损害您的字节数,但是在T-SQL中获取输入“批准”方法是通过预先创建的table
BradC

@BradC如果我可以将每行作为一个字符的表格(有点像char数组而不是字符串),那么它将有助于删除一个CTE。如果仍然必须是一行,则可能与将其作为输入变量大致相同。谢谢你的主意!
Brian J

4

C(gcc)58 56字节

@gastropner节省了2个字节

使用与我的Node.js回答相同的方法。输入字符串的大小写无关紧要。

m,i;f(char*s){for(i=0;*s?m|=1<<*s++:(i++,m&=m*2););s=i;}

在线尝试!

已评论

m,                   // m = bitmask of encountered letters
i;                   // i = counter of max. consecutive letters
f(char *s) {         // f = function taking the input string s
  for(               // main loop:
    i = 0;           //   start with i = 0 and assume m = 0 on first call
                     //   (it is forced back to 0 when the program terminates)
    *s ?             //   if we haven't reached the end of the string:
      m |= 1 << *s++ //     update m by setting the appropriate bit for this character
                     //     (with implicit modulo 32) and advance the string pointer
    : (              //   else:
        i++,         //     increment i
        m &= m * 2   //     'reduce' runs of consecutive 1's in m by AND'ing it with a
      );             //     left-shifted copy of itself (e.g. 11101 & 111010 -> 11000;
                     //     11000 & 110000 -> 10000); we stop when m = 0
  );                 // end of for()
  s = i; }           // return i

1<<*s包装是特定于实现的还是标准行为?
乔纳森·弗雷奇

@JonathanFrech我认为这是官方未定义的行为。因此,它必须是特定于实现的。
Arnauld

因为足够有趣的是,它似乎仅在运行时计算时才包装。在编译时1<<32导致0并发出数据类型大小警告。
乔纳森·弗雷希

实际上,我怀疑编译器会明确应用5位掩码。可能是在CPU级别完成的。
Arnauld

2
@ 是可以的(请参见注释:“ [...]计数操作数可以是立即数或寄存器CL。计数被屏蔽为5位,这将计数范围限制为0到31。”)
ErikF

3

C(gcc),100字节

c,o,u;n(t,e,r)char*r,*e,*t;{for(u=0,e=t;c=*t++;u=u<o?o:u)for(o=0,r=e;*r;*r++-c||(c++,r=e,++o));o=u;}

在线尝试!

说明

c,o,u;n(t,e,r)    // setup, function declaration
char*r,*e,*t;{    // K&R style
 for(u=0,e=t;     // initialize global maximum u to 0, write string start to e
 c=*t++;          // look at every character in the string
 u=u  <o?o:  u)   // funny face
  for(o=0,r=e;*r; // initialize local maximum o to 0, look at entire string again
  *r++-c||(c++,   // equal character found, search for next one
   r=e,++o));     // reset local pointer, increment local maximum
o=u;}             // return maximum character streak

在线尝试!


+1代表“ c,o,u; n(t,e,r)” :)

3

MATL12个 10字节

91:wX-dX>q

在线尝试!

说明:

91:-创建从1到91的数字列表。91是字符'[',在'Z'之后。因此,这有效地创建了从'\ x1'到'['的所有字符的列表。(我们主要希望它们在['A'-1:'Z'+ 1]范围内,但是拥有其余部分不会造成伤害,并且需要较少的字节数。)

w -隐式输入,将输入带到堆栈顶部(假设为“ TUTORIALS”)

X- -设置差异。这仅保留在输入字符串中找到的字符(按其原始顺序(“稳定”))。堆:' !"#$%&'()*+,-./0123456789:;<=>?@BCDEFGHJKMNPQVWXYZ['

d -该列表中连续元素之间的差异。堆:[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 2 1 2 1 2 1 5 1 1 1 1 1]

X> -获取这些差异中的最大值,即设置的差异中缺少的连续字母的最大数目。

q -递减以获得实际字符数


较旧:

12字节

Sud1=Y'*X>sQ

在线尝试!


这么多方法:-)
路易斯·门多

3

K(ngn / k)17 15字节

#1_{x^x^x+1}\-:

在线尝试!

- 是否仅将字符转换为数字(它们是否为负无关紧要)

{ }\ 应用函数直至收敛,并保留中间结果

x+1 将每个数字加1 x

^ “ without”-左侧列表中没有右侧列表中出现的元素

x^x^x+1xx+1

1_ 删除第一个元素

# 计数


#1_{x^x^x+1}\-
阿达姆(Adám)

@Adám是的,有一天我应该让火车上班……
ngn

将其概念化为与增量的交点,直到收敛为止都很好
约拿(Jonah)

训练工作
NGN

2

视网膜0.8.2,54字节

O`.
D`.
.
$&$&¶
T`l`_l`¶.
(.)¶\1
$1
.(.+)
$.1
O#^`
1G`

在线尝试!链接包括测试用例。说明:

O`.

将字母排序。

D`.

对字母进行重复数据删除。

.
$&$&¶

将每个字母复制在单独的行上。

T`l`_l`¶.

减少每对中的第一个。

(.)¶\1
$1

如果现在与以前的字符匹配,请将它们重新连接在一起。

.(.+)
$.1

计算所有行程的长度。

O#^`

按相反的数字顺序对它们进行排序。

1G`

以第一个(最大)为准。


2

J,16个字节

-7字节归功于FrownyFrog

[:>./a.#;._1@e.]

在线尝试!

说明

[: >./ a. #;._1@e. ]    
       a. (    )e. ]    is the ascii alphabet an element of the input:
                        this will transform the alphabet into a 1-0 array,
                        the ones representing the letters in the input
          #;._1@        split that 1-0 list up into pieces, using 0
                        as the delimiter, and transforming each chunk
                        into its length. now we have a list of ints
[: >./                  take the max 

我认为您可以使用]而不是已~.@/:~对字母进行排序,因此您无需对输入进行排序并仅保留唯一的项目。TIO-18字节
Galen Ivanov


@FrownyFrog和盖伦,谢谢你们!回想起来,我显然不需要先使用uniq / sort。
乔纳

2

C(gcc)98 92字节

感谢Jonathan Frech的建议。

仅大写。

f(char*s){int a[99]={0},i,j,k=j=i=0;for(;*s;a[*s++]++);for(;i<99;j=!!a[i++]*++j,k=j>k?j:k);}

在线尝试!


最后,您实际上不需要k;。隐式gcc返回是变量赋值的副作用,它显然是在for循环的最后一步执行的。
乔纳森·弗雷希


@JonathanFrech我不相信gcc的隐式回报。它们并不总是像我期望的那样发生,并且它们对于指针和浮点数通常根本不起作用。幸运的是,在代码高尔夫之外,我从未使用过它们!:-)
ErikF

2

杰普特 -h,9个字节

区分大小写,将输入作为字符串或字符数组。

;CôkU mÊn

尝试一下运行多个测试(第二行代替该-h标志,因此该标志可用于处理多个输入)


说明

              :Implicit input of string/array U
;C            :The lowercase alphabet
  ô           :Partition at characters returning truthy
   kU         :  Remove all characters in U from the current letter
              :  This will return a non-empty string (truthy) if the current letter ISN'T in U
     m        :Map
      Ê       :  Length
       n      :Sort
              :Implicitly output the last element in the array

@Downvoter,能否请您提供一个理由-1
粗野的

2

Perl 5,68位元组

$"=<>;map{$"=~/$_/i&&++$$_||last for$_..z;$.=$$_ if$$_>$.}a..z;say$.

在线尝试

取消高尔夫:

use feature 'say';

my $s = <>;
my $r;
for ('a' .. 'z') {
    my $c = 0;
    for ($_ .. 'z') {
        last if $s !~ /$_/i;
        $c++;
    }
    $r = $c if $c > $r;
}
say($r);

2

碳(gcc)66 65 63字节

假设输入仅包含小写字母。首先,它遍历字符串,并根据看到的字母设置整数位。接下来,它计算整数中最长的1位条纹。

编辑:a是全局的,因此将在第一次调用时初始化为0。第二个循环确保返回之前将其重置为0。因此,我们可以避免手动重置它。

a,l;f(char*s){for(l=0;*s;)a|=1<<*s++-97;for(;a;l++)a&=a*2;s=l;}

在线尝试!


2

Perl 5,62 + 2(-nF标志)= 64字节

$c[ord lc$_]=1for@F;$y[y///c]++for"@c "=~/((1 )+)/g}{say@y/2|0

在线尝试

Perl 5,68位元组

<>=~s/./$c[ord lc$&]=1/gre;$y[y///c]++for"@c "=~/((1 )+)/g;say@y/2|0

在线尝试


1
不错的方法!我不认为在所有的方法......你可以用节省几个字节-pF,并-MList::Util+(max)获得56:在线试试吧!
Dom Hastings

@DomHastings -MList::Util=max将16字节添加到结果分数中。
Denis Ibaev

如果我正确理解了新的评分标准,则不会将命令行标志计为字节,而是将其计为单独计分的语言,因此不是Perl,而是带有-MList::Util+(max) -pF或类似功能的Perl 。codegolf.meta.stackexchange.com/a/14339/9365
Dom Hastings

2

SQLite 265

WITH w AS(SELECT'a'w),n AS(SELECT 1 n UNION ALL SELECT n+1 FROM n LIMIT(SELECT length(w)FROM w)),l AS(SELECT substr(w,n,1)l FROM n,w)SELECT max(v)FROM(SELECT min(n)v FROM(SELECT*FROM l,n EXCEPT SELECT l.l,unicode(l.l)-unicode(b.l)d FROM l,l b WHERE d>0)GROUP BY l);

取消高尔夫:

WITH w AS (SELECT 'antidisestablishmentarianism' w)
   , n AS (SELECT 1 n
           UNION ALL
           SELECT n+1 FROM n
           LIMIT (SELECT length(w) FROM w) )
   , l AS (SELECT DISTINCT substr(w,n,1) l FROM n,w ORDER BY l)
   , d AS (
           SELECT l,n FROM l,n
           EXCEPT
           SELECT a.l l, unicode(a.l) - unicode(b.l) d 
           FROM l a, l b 
           WHERE d > 0 
           )

SELECT max(v) FROM ( SELECT min(d.n) v FROM d GROUP BY d.l );

2

Brachylog14 13 12字节

{⊇pS∧ẠsSl}ᶠ⌉

在线尝试!

{        }ᶠ    % Find all values that satisfy this predicate
           ⌉   % And get their maximum
               % The predicate being:
 ⊇pS           % There exists a permutation of a subset of the input
               %  Call it S
    ∧          % And, 
      sS       % S is a substring of
     Ạ         %  the set of alphabets, Ạ, 
        l      % Then, the length of that substring is the return value of the 
               %  predicate

足够慢,以至于无法在TIO上输入“反复权主义”。+1字节相对更快:

13字节

{dosS∧ẠsSl}ᶠ⌉

在线尝试!

使用dos代替⊇p:S是输入的经过d复制的oubstring s,而不仅仅是某些子集的某些排列。


1

Haskell,87个字节

import Data.List
maximum.map length.filter(`isInfixOf`['a'..'z']).subsequences.nub.sort

在线尝试!

要求小写字符

说明:

maximum.map length.filter(`isInfixOf`['a'..'z']).subsequences.nub.sort
                                                                  sort {- sort the characters -}
                                                              nub      {- remove duplicates -}
                                                 subsequences          {- all subsequences -}
                   filter(`isInfixOf`['a'..'z'])                       {- all characters are adjacent -}
        map length                                                     {- length of filtered subsequences -}
maximum                                                                {- maxmimum length -}


1

Pyth-11个字节

le@.:G).:S{

输入必须用引号引起来。如果不允许:

Pyth-12个字节

le@.:G).:S{z

说明:

l(
  e(
    @(
      .:(G),
      .:(
         S(
           {(Q)
         )
      )
    )
  )
)
length(
    last element(
        intersection(
            all positive length substrings(the alphabet as string),
            all positive length substrings(
                sorted(
                    uniquified(input)
                )
            )
        )
    )
)


1

Java 8,77字节

int i,j,m;
c->{for(i=j=0;(m=j<c.length?m|1<<c[j++]:m&m*2+0*++i)>0;);return i;}

阿诺尔德的C 答案港。在这里在线尝试。

取消高尔夫:

int i, j, m; // instance variables of the surrounding class - initialised to 0
c -> { // lambda - c is of type char[]; return type is int
    for(i = j = 0; // i is the length of the longest run, j is used to step through c - both start at 0
        (m = j < c.length // work with the bitmask of all the letters present in c: if we have not reached the end of c ...
             ? m | 1 << c[j++] // ... set the bit corresponding to the current character, advance one character ...
             : m & m * 2 + 0 * ++i) > 0 ;) ; // ... else reduce runs of consecutively set bits in m by AND-combining it with a left-shifted copy of itself until m hits 0
    return i; // return the result - by now m is back to 0
}

1

> <>,63字节

从stdin读取小写字符,将数字输出到stdout。

0l55*)?\
8/?(0:i<]r1~r[-*c
~/00
}</?)@:{:*+1/?(3l
  \~:03. ;n~/

在线尝试!

0l55*)?\             Push 26 zeroes onto the stack

Record which characters are used
      i              Read a character from the input
 /?(0:               Check if it is -1, marking the end of the input
8             -*c    Subtract 96 from the character code, 
                         giving 1 for 'a', 2 for 'b' etc.
            r[       Pop that many values on to a new stack and reverse 
                         it, putting that character's value at the top of 
                         the stack
          1~         Write 1 to that value
        ]r           Return the stack back to it's normal state

Count the longest run of ones in the stack
  00                 Push values for currentRun = 0, and bestRun = 0
}                    Move bestRun to the bottom of the stack
            /?(3l    Check if there are only 2 values left on the stack
          +1         Increment currentRun
         *           Multiply currentRun by the next value in the stack, 
                         resetting it to 0 if the run is broken
  /?)@:{:            Check if currentRun > bestRun
  \~:                Overwrite bestRun if so
     03.             Jump back to the start of loop
         ;n~/        Once all values have been consumed, 
                         print bestRun and exit
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.