单个数字的最长重复子序列


17

挑战:

给定一个正整数,输出至少出现两次的最长的单个数字子序列,并且具有另一个数字的边界(或整数的开始/结尾)。

一个例子:

输入:7888885466662716666
单个数字的最长子序列为888887[88888]5466662716666),长度为5。但是,该子序列在整数中仅出现一次。
相反,输入的结果7888885466662716666应为666678888854[6666]271[6666]),因为它(至少)出现两次。

挑战规则:

  • 子序列的长度优先于其发生的次数。(即输入8888858888866656665666,我们输出88888[88888]5[88888]66656665666;长度5,发生两次),而不是66688888588888[666]5[666]5[666];长度3,发生三次)。
  • 如果多个子序列的长度相等,则输出出现次数最大的子序列。即,具有输入3331113331119111,输出我们111333[111]333[111]9[111];长度为3时,发生三次),而不是333[333]111[333]1119111;长度3为好,但发生两次)
  • 如果多个子序列的出现次数和长度相等,则可以输出其中一个或全部(以任何顺序)。即,具有输入777333777333,可能的输出是:777; 333; [777, 333]; 或[333, 777]
  • 子序列必须具有其他数字的边界(或整数的开始/结尾)。即,输入122222233433结果为331222222[33]4[33];长度2,出现两次)而不是2221[222][222]33433,长度3,两次出现都无效)。
    • 这适用于所有计入出现次数计数器的数字。即,输入811774177781382结果为8[8]117741777[8]13[8]2;长度1,发生三次,三次)而不是77811[77]41[77]781382/ 811[77]417[77]81382;长度2,发生两次,一次无效)或18[1][1]774[1]7778[1]382;长度1,发生四次,两次无效。
  • 您可以假设输入内容不包含任何数字0(它将与匹配[1-9]+)。(这是为了避免不得不处理10002000应该输出的测试用例,默认情况下000大多数语言都将输出0。)
  • 您可以假定输入将始终包含至少一个有效输出。
  • I / O都很灵活。可以是数字/字节/字符的列表/数组/流,也可以是字符串而不是单个整数。

通用规则:

  • 这是,因此最短答案以字节为单位。
    不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能短的答案。
  • 标准规则适用于您的答案,因此您可以使用STDIN / STDOUT,具有正确参数的函数/方法和返回类型的完整程序。你的来电。
  • 默认漏洞是禁止的。
  • 如果可能的话,请添加一个带有测试代码的链接。
  • 另外,强烈建议为您的答案添加说明。

测试用例:

Input:  7888885466662716666 / [7,8,8,8,8,8,5,4,6,6,6,6,2,7,1,6,6,6,6]
Output: 6666                / [6,6,6,6]

Input:  3331113331119111 / [3,3,3,1,1,1,3,3,3,1,1,1,9,1,1,1]
Output: 111              / [1,1,1]

Input:            777333777333                   / [7,7,7,3,3,3,7,7,7,3,3,3]
Possible outputs: 777; 333; [777,333]; [333;777] / [7,7,7]; [3,3,3]; [[7,7,7],[3,3,3]]; [[3,3,3],[7,7,7]]

Input:  122222233433 / [1,2,2,2,2,2,2,3,3,4,3,3]
Output: 33           / [3,3]

Input:  811774177781382 / [8,1,1,7,7,4,1,7,7,7,8,1,3,8,2] 
Output: 8               / [8]

Input:  555153333551 / [5,5,5,1,5,3,3,3,3,5,5,1] 
Output: 1            / [1]

Input:            12321              / [1,2,3,2,1]
Possible outputs: 1; 2; [1,2]; [2,1] / [1]; [2]; [[1],[2]]; [[2],[1]]

Input:  944949949494999494 / [9,4,4,9,4,9,9,4,9,4,9,4,9,9,9,4,9,4]
Output: 4                  / [4]

Input:  8888858888866656665666 / [8,8,8,8,8,5,8,8,8,8,8,6,6,6,5,6,6,6,5,6,6,6]
Output: 88888                  / [8,8,8,8,8]

Input:  1112221112221111               / [1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,1]
Output: 111; 222; [111,222]; [222,111] / [1,1,1]; [2,2,2]; [[1,1,1],[2,2,2]]; [[2,2,2],[1,1,1]]

Input:  911133111339339339339339 / [9,1,1,1,3,3,1,1,1,3,3,9,3,3,9,3,3,9,3,3,9,3,3,9]
Output: 111                      / [1,1,1]

1
建议的测试用例:8888858888866656665666。如果我正确地解释了挑战,那么Brachylog和05AB1E解决方案都会失败。
Xcoder先生18年

@ Mr.Xcoder已添加,谢谢。
凯文·克鲁伊森

@Arnauld Hmm,我认为无论如何它都会是赢家之一,因为它的出现次数与222被其他整数限定的次数一样多。我猜我们不应该算是的子字符串的出现1111。实际上,最好等待OP。
Xcoder先生18年

2
@Arnauld对于1112221112221111这些都是子序列和他们的罪状:1111 (1)111 (2)222 (2)。由于我们只输出序列至少发生两次,则输出可以是以下之一:111222[111,222][222,111]。(有关更多信息,请参阅第四条规则。)基本上1111将永远只计为1111,而不会计为11111111。我将添加您的测试用例,但输出是111和之一或全部都是222
凯文·克鲁伊森

Answers:


6

05AB1E,14个字节

γТ1›ÏD€gZQÏ.M

在线尝试!

说明

γ                # group consecutive equal elements
 Т              # count the occurrence of each group among the list of groups
   1›Ï           # keep only groups with a count greater than 1
      D€gZQÏ     # keep only those with a length equal to the greatest length
            .M   # get the most common item

@Riley:不幸的是,这将得到第一个元素,不一定是最常见的元素。
Emigna

糟糕,我错过了那颗子弹。
莱利

5

果冻,12字节

Œgœ-Q$LÐṀÆṃ'

在线尝试!

先前版本– 14个字节

ŒgŒQ¬TịƲLÐṀÆṃ'

在线尝试!

怎么运行的?

Œgœ-Q$LÐṀÆṃ' – Full program. Receives a list of digits as input.
Œg           – Group equal adjacent values.
  œ-Q$       – Multiset difference with itself deduplicate.
      LÐṀ    – Keep those that are maximal by length.
         Æṃ' – Mode. Returns the most common element(s).
-------------------------------------------------------------------------
ŒgŒQ¬TịƲLÐṀÆṃ' – Full program. Receives a list of digits as input.
Œg             – Group equal adjacent values.
  ŒQ           – Distinct sieve. Replace the first occurrences of each value by 1.
                 and the rest by 0. [1,2,3,2,3,2,5]ŒQ -> [1,1,1,0,0,0,1]       
    ¬T         – Negate and find the truthy indices.
      ịƲ       – Then index in the initial list of groups.
               – This discards the groups that only occur once.
        LÐṀ    – Find all those which are maximal by length.
           Æṃ' – And take the mode.

5

JavaScript(ES6),79 73 68字节

将输入作为字符串。返回一个整数。

s=>[...s,r=q=0].map(o=d=>q=s^d?o[!o[q]|r[q.length]?q:r=q]=s=d:q+d)|r

在线尝试!

已评论

s =>                      // s = input string, also used as the current digit
  [ ...s,                 // split s into a list of digit characters
    r =                   // r is the final result
    q =                   // q is the current digit sequence
    0                     // append a final dummy entry to force the processing of the last
  ]                       // sequence
  .map(o =                // o is an object used to keep track of encountered sequences
       d =>               // for each digit d in the array defined above:
    q =                   //   update q:
      s ^ d ?             //     if d is not equal to the current digit:
        o[                //       this statement will ultimately update o[q]
          !o[q] |         //         if q has not been previously seen
          r[q.length] ?   //         or the best result is longer than q:
            q             //           leave r unchanged
          :               //         else:
            r = q         //           set r to q
        ] = s = d         //       reset q to d, set the current digit to d
                          //       and mark q as encountered by setting o[q]
      :                   //     else:
        q + d             //       append d to q
  ) | r                   // end of map(); return r, coerced to an integer

也许我在这里说的是不正确的,但是由于...s将输入转换为数字字符列表,将输入作为数字字符列表而不是字符串开始不是更短吗?我允许灵活的I / O。(但我假设它会干扰您代码的另一部分?)
Kevin Cruijssen 18/09/17

2
@KevinCruijssen问题是我需要额外的迭代来处理最后一个序列。因此,[...s,0]即使s已经是列表,我也需要这样做。
Arnauld

4

视网膜,56字节

L`(.)\1*
O`
L$m`^(.+)(¶\1)+$
$#2;$1
N`
.+;

N$`
$.&
-1G`

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

L`(.)\1*

列出所有最大重复的数字子序列。

O`

按顺序对列表进行排序。

L$m`^(.+)(¶\1)+$
$#2;$1

列出所有多个子序列及其“计数”。

N`

按计数的升序排序。

.+;

删除计数。

N$`
$.&

按长度的升序排序。(在长度相等的情况下,保留由于计数而导致的先前顺序。)

-1G`

保留最后一个即最长的值。


4

R,102字节

function(i)rep(names(sort(-(x=(x=table(rle(i)))[rowSums(x>1)>0,,drop=F])[m<-max(rownames(x)),])[1]),m)

在线尝试!

由于还没有R答案,所以我决定尝试一下,好吧...这并不容易。我真的不知道这是否是一个好方法,但是可以了。

字符的输入和输出。


对于这个挑战,R接近100字节是相当不错的。
ngm


3

Python 2中123 120个字节

import re
def f(s):r=re.findall(r'(\d)(\1*)',s);c=r.count;print max((len(a+b)*(c((a,b))>1),c((a,b)),a+b)for a,b in r)[2]

在线尝试!


3

Powershell,101字节

($args|sls '(.)\1*'-a|%{$_.Matches}|group|?{$_.Count-1}|sort @{e={$_.Name.Length,$_.Count}})[-1].Name

说明性的测试脚本:

$f = {

(
    $args|          # for each argument (stings)
    sls '(.)\1*'-a| # searches all
    %{$_.Matches}|  # regex matches
    group|          # group it (Note: Count of each group > 0 by design)
    ?{$_.Count-1}|  # passthru groups with Count not equal 1
    sort @{         # sort all groups by 2 values
        e={$_.Name.Length,$_.Count}
    }
)[-1].Name          # returns name of last group (group with max values)

}

@(
    ,('7888885466662716666', '6666')
    ,('3331113331119111', '111')
    ,('777333777333', '777','333')
    ,('122222233433', '33')
    ,('811774177781382', '8')
    ,('555153333551','1')
    ,('12321', '1','2')
    ,('944949949494999494','4')
    ,('8888858888866656665666','88888')
    ,('1112221112221111','111','222')
) | % {
    $s,$e = $_
    $r = &$f $s
    "$($r-in$e): $r"
}

输出:

True: 6666
True: 111
True: 777
True: 33
True: 8
True: 1
True: 1
True: 4
True: 88888
True: 111

3

Python 2114 113字节

-1字节归功于TFeld

p='';r=[];C=r.count
for c in input():r+=['']*(c!=p);r[-1]+=c;p=c
print max((len(w),C(w),w)for w in r if~-C(w))[2]

在线尝试!


3

Haskell,72个字节

import Data.Lists
g!x|y<-countElem x g=(y>1,1<$x,y)
(argmax=<<(!)).group

怎么运行的

(argmax=<<(!)).group       -- expands to: f i = argmax (group i !) (group i)
    group                  -- split the input list into subsequences of equal digits
                           -- e.g. "1112211" -> ["111","22","11"]

                           -- find the element of this list where the function !
                           -- returns the maximum value. First parameter to !
                           -- is the grouped input list, second parameter the
                           -- the element to look at 

g!x|
    y<-countElem x g       -- let y be the number of occurrences of x in g
  = (  ,   ,  )            -- return a triple of
     y>1                   -- a boolean y>1  (remember: True > False)  
        1<$x               -- length of x (to be exact: all elements in x
                           -- replaced by 1. This sorts the same way as the
                           -- length of x)
             y             -- y
                           -- a triples sorts lexicographical

因为Data.Lists不是基础的一部分,您是否不需要使用Haskell +列表作为语言?
18-09-18

@BWO:不知道。即使导入了异国情调的库(例如,Gloss用于图形输出或Matrix),我也一直使用普通的“ Haskell” 。如果我不想包括导入的字节数,则使用“ Haskell + something”。我认为我们在meta上有这个话题,但是我找不到了。如果我没记错的话,我们没有“标准库”的一般定义。Haskell应该参考什么?GHC的基础Haskell Plattform,Haskell报告,还有其他内容吗?
nimi

IMO应该和C / JavaScript / ..一样(如果重要),我们需要使用Haskell(GHC)Haskell(Hugs)等,因为实现在PPCG上指定了一种语言。因此,对于GHC答案,包括基数以及所有其他答案,我将不知道:D
18'23

您是否有TIO链接以便可以进行测试?还是该Data.Lists库在TIO或其他在线Haskell编译器上不可用?
凯文·克鲁伊森

1
@KevinCruijssen:是的Data.Lists,在TIO上缺少。您可以使用此版本进行测试。
nimi

3

R,85字节

function(x,R=rle(x),a=ave(R$v,R,FUN=length))rep(R$v[o<-order(a<2,-R$l,-a)[1]],R$l[o])

在线尝试!

  • 输入:分隔整数的向量,例如c(1,8,8...)

  • 输出:分隔整数数字的向量

展开代码并提供说明:

function(x){                # x is a vector of digits : e.g. c(1,1,8,8,1,1)

R = rle(x)                  # Get the sequences of consecutive repeating digits
                            # doing run length encoding on x, i.e. : R is a list
                            # with the digits (R$values) and the number of their
                            # consecutive occurrencies (R$lengths)
                            # N.B. you can use R$v for R$values and R$l for R$lenghts

a=ave(R$v,R,FUN=length)     # Group R$v by R$l AND R$v, count the occurrencies 
                            # for each group and "unroll" the value of each 
                            # group to the original R$v length.
                            # Here basically we count the occurrencies of the same 
                            # sequence.

o<-order(a<2,-R$l,-a)[1]    # Get the indexes used to order by a < 2 then by -R$l and
                            # finally by -a; store the first index in "o".
                            # Here basically we use order to select the first sequence 
                            # repeated at least twice, in case of ties the sequence 
                            # with the greatest length and in case of ties the most 
                            # repeated sequence.

rep(R$v[o],R$v[o])          # Using the index "o", we reconstruct the sequence repeating
                            # R$l[o] times R$v[o]
}

接受整数或字符数字向量的替代版本:

R,88字节

function(x,R=rle(x),a=ave(R$v,R,FUN=length))rep(R$v[o<-tail(order(a>1,R$l,a),1)],R$l[o])

在线尝试!

  • 输入:由分隔的字符或数字组成的向量,例如c("1","8","8"...)c(1,8,8...)

  • 输出:如果输入是字符向量,则为分隔字符的向量;如果输入是数字向量,则为数字向量


您可以添加说明吗?我不明白它的运作方式。
JayCe

@JayCe:完成了!(我为非R用户添加了众所周知的详细信息;))
digEmAll

ty!现在有道理了。
JayCe

2

红色256250字节

func[s][p: func[b][sort parse b[collect[any keep[copy a skip thru any a]]]]first
last sort/compare collect[foreach d p p s[if 1 < k: length? to-block d[keep/only
reduce[form unique d k]]]]func[x y][(reduce[length? x/1 x/2])< reduce[length? y/1 y/2]]]

在线尝试!

真的,这次真的很长的解决方案...(叹气)

将输入作为字符串。

说明:

f: func [ s ] [
    p: func [ b ] [                        ; groups and sorts the adjacent repeating items
        sort parse b [ 
            collect [                      
                any keep[
                    copy a skip thru any a ; gather any item, optionally followed by itself  
                ]
            ]
        ]
    ]
    t: copy []
    foreach d p p s [                     ; p p s transforms the input string into a block of sorted blocks of repeating digits
        if 1 < k: length? to-block d [    ; filters only the blocks that occur more than once
            insert/only t reduce [ form unique d k ] ; stores the digits and the number of occurences
                                          ; "8888858888866656665666" -> [["5" 3] ["666" 3] ["88888" 2]]
        ]
    ]
    first last sort/compare t func [ x y ] ; takes the first element (the digits) of the last block of the sorted block of items
        [ (reduce [ length? x/1 x/2 ]) < reduce [ length? y/1 y/2 ] ] ; direct comparison of the blocks
]

2

Java(JDK 10),213字节

s->{int l=99,X[][]=new int[10][l],d,D=0,m=0,M=0;for(var x:s.split("(?<=(.))(?!\\1)"))X[x.charAt(0)-48][x.length()]++;for(;M<1&&l-->1;)for(d=0;d++<9;)if((m=X[d][l])>1&m>M){M=m;D=d;}for(;l-->0;)System.out.print(D);}

在线尝试!

说明(过时)

s->{                                    // Lambda for Consumer<String>
 int l=99,                              //  Length of token, max is 99.
     X[][]=new int[10][l],              //  Array containing the occurrences per token
     d,                                 //  digit value
     D=0,                               //  digit holder for best sequence candidate
     m=0,                               //  holder of the current candidate
     M=0;                               //  best candidate for the current length of token.
 for(var x:s.split("(?<=(.))(?!\\1)"))  //  Tokenize the string into digit-repeating sequences
  X[x.charAt(0)-48][x.length()]++;      //   Add one occurrence for the token
 for(;M<1&&l-->1;)                      //  While no value has been found and for each length, descending. Do not decrease length if a value has been found.
  for(d=0;d++<9;)                       //   for each digit
   if((m=X[d][l])>1&m>M){               //    if the current occurrence count is at least 2 and that count is the current greatest for the length
    M=m;D=d;                            //     mark it as the current best
   }                                    //
 for(;l-->0;)System.out.print(D);       //  Output the best-fitting subsequence.
}                                       // 

学分


1
恐怕您的j*o>M支票上有一个小瑕疵。如果我正确理解的话会花费最大length * occurrence-count。但是对于1113311133933933933933例如这样的测试用例,111则将为(3 * 2 = 6),而33将为(2 * 6 = 12)。因此,它输出33的次数最多,而不是发生111的时间最长的次数至少两次。此外,var r="";for(;O-->0;)r+=D;return r;可以golfed到for(;O-->0;)System.out.print(D);Java中10,甚至在Java中11短:return(D+"").repeat(O);
凯文·克鲁伊森

@KevinCruijssen我想我已经解决了。
OlivierGrégoire18年

1
确实看起来更好,同时又是打高尔夫球的好方法。您只是忘了更新您的解释。然后,您可以将1个字节再打高尔夫球int X[][]=new int[10][99],d,l=99,int l=99,X[][]=new int[10][l],d,
凯文·克鲁伊森

1
@KevinCruijssen谢谢!我还通过写d++<9而不是来打了一个字节++d<10。抱歉,其他人:我今天很累= _ =
OlivierGrégoire18年

2

Ruby68 67字节

->a{(b=a.chunk &:+@).max_by{|x|[(c=b.count x)<2?0:x[1].size,c]}[1]}

在线尝试!

输入和输出字符数组。

该方法非常简单:我们确定连续数字的游程(chunk使用一元+作为标识函数)并取最大值-首先按游程的大小(如果其出现​​次数小于2,则重置为零),然后按计数本身。


2

PCRE,152个字节

(\d)(?<!(?=\1)..)(?=(\1*)(?!\1).*(?!\1).\1\2(?!\1))(?!(?:(?=\2((\3?+)(\d)(\5*)))){1,592}?(?=\2\3.*(?!\5).\5\6(?!\5))(?:\1(?=\1*\4\5(\7?+\5)))*+(?!\1))\2

在以下位置查看其运行情况:https//regex101.com/r/0U0dEp/1(只需查看每个测试用例中的第一个匹配项)

这只是为了好玩,因为正则表达式本身并不是真正的编程语言,而且解决方案是有限的:P

由于零宽度的组(例如,(?:)+仅匹配一次且不会无限期地重复),并且由于PCRE在内部对具有限制的组的副本进行了量化,因此我不得不在其中使用一个幻数(“ {1,592}”),意味着我们最多只能查询592个连续的数字集,以找到可能比当前正在检查的数字更长的竞争性数字集。有关此概念的更多信息,请参见此处


1

Perl 5,88个字节

my($m,%s);++$i%2*$s{$_}++&&($n=$s{$_}/9+length)>$m&&($a=$_,$m=$n)for pop=~/((.)\2*)/g;$a

在线尝试!

略有偏差,经过测试:

sub f {
  my($m,%s);
  my($i,$n,$a);           #not needed in golfed version
  ++$i % 2  *  $s{$_}++
  && ($n=$s{$_}/9+length) > $m
  && ($a=$_, $m=$n)
    for pop=~/((.)\2*)/g; #i.e. 7888885466662716666 => 7 88888 5 4 6666 2 7 1 6666
  $a
}
for(map[/\d+/g],split/\n/,join"",<DATA>){ #tests
  my($i,@e)=@$_;
  printf "%-6s   input %-24s   expected %-10s   got %s\n",
    (grep f($i) eq $_, @e) ? "Ok" : "Not ok", $i, join('|',@e), f($i);
}
__DATA__
Input:  7888885466662716666     Output: 6666
Input:  3331113331119111        Output: 111
Input:  777333777333            Output: 777|333
Input:  122222233433            Output: 33
Input:  811774177781382         Output: 8
Input:  555153333551            Output: 1
Input:  12321                   Output: 1|2
Input:  944949949494999494      Output: 4
Input:  8888858888866656665666  Output: 88888
Input:  1112221112221111        Output: 111|222


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.