矮胖vs.平滑弦


29

考虑一个长度为N的字符串,例如Peanut ButterN =13。请注意,该字符串中有N-1对相邻字符。因为Peanut Butter,12对中的第一个是Pe,第二个是ea,最后一个是er

当两对大多数是不同的字符时,字符串具有粗大的质量,例如chUnky
当这些对几乎都是相同的字符时,字符串具有平滑的质量,例如sssmmsss

将字符串的组性定义为具有两个不同字符的线对数与线对总数(N-1)的比率。

将字符串的平滑度定义为具有两个相同字符的线对数与线对总数(N-1)的比率。

例如,Peanut Butter只有一对具有相同字符(tt)的对,因此其平滑度为1/12或0.0833,而其块状度为11/12或0.9167。

空字符串和仅包含一个字符的字符串被定义为100%平滑和0%厚实。

挑战

编写一个程序,该程序采用任意长度的字符串,并输出其块状或平滑度比率作为浮点值。

  • 通过stdin或命令行获取输入,或者您可以编写一个带有字符串的函数。
  • 您可以假设输入字符串仅包含可打印的ASCII字符(因此为单行)。
  • 将浮点数输出到stdout到小数点后4位或更多位,或者如果编写了函数,则可以选择将其返回。不需要传达任何信息的小数位,例如0可以用代替0.0000
  • 根据需要选择块状或光滑度。只要确定您的程序输出哪个即可。

以字节为单位的最短代码获胜。

例子

Peanut Butter→粗0.91666666666度:,平滑度:0.08333333333
chUnky→粗1.0度:,平滑度:0.0
sssmmsss→粗0.28571428571度:,平滑度:0.71428571428
999→粗0.0度:,平滑度:1.0
AA→粗0.0度:,平滑度:1.0
Aa→粗1.0度:,平滑度:0.0
!→粗0.0度:,平滑度:1.0
[空字符串]→粗度:0.0,光滑度:1.0

奖金的问题:你更喜欢哪一个矮胖或平滑的字符串


8
-1没有多余的标签。
丹尼斯

22
+1确凿证据表明矮胖的花生酱应为默认值。
BrainSteel

有些语言很难阅读所有输入内容。可以假定输入是换行符终止的吗?
丹尼斯

@丹尼斯是的,很好。
加尔文的业余爱好

9
如果您是计算机,则@BrainSteel Chunky仅应为默认值;他们喜欢有可用的块。为人们制作的花生酱应隐藏那些实现细节,并为用户提供像丝绸一样的光滑感。
Geobits,2015年

Answers:


7

APL,10个字节

这将从stdin读取输入,并将块状打印到stdout。该算法与用于J解决方案的算法相同。

(+/÷⍴)2≠/⍞

19

CJam,19个字节

q_1>_@.=:!1b\,d/4mO

100%矮胖的源代码,用于计算矮胖

在线尝试这种笨拙的优点。

怎么运行的

q_                  e# Read from STDIN and push a copy.
  1>_               e# Discard the first character and push a copy.
     @              e# Rotate the original on top.
      .=            e# Vectorized comparison (1 if equal, 0 if not).
        :!          e# Mapped logical NOT (0 if equal, 1 if not).
          1b        e# Base 1 conversion (sum).
            \,      e# Swap with the shortened string and push its length.
              d/    e# Cast to double and divide.
                4mO e# Round to four decimal places.

显然,将NaN舍入到小数点后4位为0。


1
我认为您不需要将其四舍五入到4位数字。它说“ 4个或更多”,并且不需要尾随零。这比2ew我尝试的方法要优雅得多。0/1字母特殊情况使我丧命。
Reto Koradi

@RetoKoradi Rounding将NaN映射为0。我不知道更短的方法。
丹尼斯

是的,在使用它的同时,我只是注意到您为1个字符的输入获得了NaN。到目前为止,简短的输入是最痛苦的部分。顺便说一句,在线链接的代码与您发布的版本略有不同。一_动。不确定是否重要。
Reto Koradi

@RetoKoradi当然可以。链接的代码不会100%粗大。:P
丹尼斯

3
@AlexA。果酱与水果块的比例至少为10%。
丹尼斯

13

Pyth,13 12字节

csJnVztz|lJ1

完整的矮矮胖胖的代码计算矮胖。

示范。 测试线束。

csJnVztz|lJ1
                 Implicit: z = input()
   nV            n, !=, vectorized over
     z           z
      tz         z[:-1]
                 V implitly truncates.
  J              Store it in J.
 s               sum J
c                floating point divided by
         |       logical or
          lJ     len(J)
            1    1

在在线版本中,将输入留空时会出现错误。据我所知,它未能通过最后一个测试用例。
Reto Koradi

@RetoKoradi这很奇怪-在脱机版本中可以正常工作。在线网站可能是一个错误。
isaacg

@RetoKoradi确认- z在线使用空输入时,非常会引起错误。我将修复该错误。这段代码很好。
isaacg 2015年

如果我在输入框中单击一次回车,它将起作用。但是其他字符串不需要在结尾处返回。在输入框中未键入任何内容时,似乎根本没有任何输入,并且当您尝试使用输入时,您的代码会炸裂。
Reto Koradi

@RetoKoradi谢谢。我想我知道这个问题,应该不难解决。
isaacg

8

TI-BASIC,46个字节

Input Str1
If 2≤length(Str1
mean(seq(sub(Str1,X,1)=sub(Str1,X-1,1),X,2,length(Str1
Ans

sub(x1,x2,x3给出字符串的子字符串,该子字符串x1从number开始(从一个位置开始),以number x2结束x3,然后seq(构建一个序列。

给出平滑度值。该Ans变量0默认情况下是默认值,因此我们不需要ElseIf语句中添加或Ans预先存储任何内容。


7

Matlab(37 36字节)

可以使用以下匿名函数来完成此操作,该函数返回大块:

f=@(x)nnz(diff(x))/max(numel(x)-1,1)

评论:

  • 在旧的Matlab版本(例如R2010b)中,您需要+将char数组x转换为double数组:

    f=@(x)nnz(diff(+x))/max(numel(x)-1,1)`
    

    但是最新版本(在R2014b中测试)不是这种情况,它节省了一个字节。感谢乔纳斯的评论。

  • 带有的表达式max处理一字符和零字符的情况(用于块)

例:

>> f=@(x)nnz(diff(x))/max(numel(x)-1,1)
f = 
    @(x)nnz(diff(x))/max(numel(x)-1,1)

>> f('Peanut Butter')
ans =
   0.9167

在R2014b上,diff('abc')不会产生警告。
乔纳斯(Jonas)

6

> <>40 36字节

00ii:0(?v:@=1$-{+{1+}}20.
~:0=+,n;>~

该程序返回字符串的块状性。

说明

00i         Push 0 (# unequal pairs), 0 (length of string - 1) and read first char

[main loop]

i           Read a char
:0(?v       If we've hit EOF, go down a row
:@=1$-      Check (new char != previous char)
{+          Add to unequal pairs count
{1+         Increment length by 1
}}20.       Continue loop

[output]

~~          Pop last two chars (top one will be -1 for EOF)
:0=+        Add 1 to length if zero (to prevent division by zero errors)
,           Divide, giving chunkiness
n;          Output and halt

先前提交的内容(37 + 3 = 40字节)

l1)?v1n;
n,$&\l1-}0& \;
l2(?^$:@=&+&>

该程序返回字符串的平滑度。通过-s标志输入,例如

py -3 fish.py chunkiness.fish -s "Peanut Butter"

6

C#, 94 89字节

不到100字节,所以我想这本身就是某种胜利的形式吗?

这是一个函数定义(按规范允许),该函数返回输入字符串的平滑度

Func<string,float>(s=>s.Length>1?s.Zip(s.Skip(1),(a,b)=>a==b?1f:0).Sum()/(s.Length-1):1);

非常简单,如果长度为0或1,则返回1,否则将字符串与自身进行比较(减去第一个字符),然后返回相同对数除以对数。

编辑-将子字符串替换为“跳过”。菜鸟错误!


5

J,14 13字节

计算组块。J 0 % 0等于0表示荣誉。

(]+/%#)2~:/\]

在线尝试

这里是一个解释:

   NB. sample input
   in =. 'sssmmsss'

   NB. all infixes of length 2
   2 ]\ in
ss
ss
sm
mm
ms
ss
ss

    NB. are the parts of the infix different?
    2 ~:/\ in
0 0 1 0 1 0 0

    NB. sum and item count of the previous result
    (+/ , #) 2 ~:/\ in
2 7

    NB. arithmetic mean: chunkiness
    (+/ % #) 2 ~:/\ in
0.285714

    NB. as a tacit verb
    (] +/ % #) 2 ~:/\ ]

    NB. 0 divided by 0 is 0 in J
    0 % 0
0

(]+/%#)2~:/\]保存1个字节。
FrownyFrog

@FrownyFrog酷!我怎么会错过呢?
FUZxxl

您可以添加带有测试代码的TIO链接吗?
凯文·克鲁伊森

4

CJam,23个字节

q_,Y<SS+@?2ew_::=:+\,d/

说明:

q                           e# read input
 _,                         e# its length
   Y<                       e# is less than 2?
     SS+                    e# then a smooth string
        @?                  e# otherwise the input
          2ew               e# pairs of consecutive characters
             _::=           e# map to 1 if equal, 0 if not
                 :+         e# sum (number of equal pairs)
                   \,       e# total number of pairs
                     d/     e# divide

这输出平滑率。


4

CJam,16个字节

1q2ew::=_:+\,d/*

计算平滑度的欺骗性源代码。

对于长度为0或1的输入,这将在错误退出之前输出正确的结果。使用Java解释器,错误输出将输出到STDERR(应该如此)。

如果您在线尝试代码,则只需忽略输出的最后一行即可。

怎么运行的

1q               e# Push a 1 and read from STDIN.
  2ew            e# Push the overlapping slices of length 2.
                 e# This will throw an error for strings of length 0 or 1,
                 e# so the stack (1) is printed and the program finishes.
     ::=         e# Twofold vectorized comparision.
        _:+      e# Push a copy and add the Booleans.
           \,    e# Swap with the original and compute its length.
             d/  e# Cast to double and divide.
               * e# Multiply with the 1 on the bottom of the stack.

3

朱莉娅52字节

光滑度!

s->(n=length(s))<2?1:mean([s[i]==s[i+1]for i=1:n-1])

这将创建一个未命名的函数,该函数接受字符串并返回数字值。

如果输入的长度小于2,则平滑度为1,否则我们将采用逻辑数组的平均值来计算相同相邻字符的比例。


3

Nim,105 96 91字节

proc f(s):any=
 var a=0;for i,c in s[.. ^2]:a+=int(s[i+1]!=c)
 a.float/max(s.len-1,1).float

试图学习尼姆。这将计算字符串的块状性。

如果我尝试将其读为Python,则缩进看起来一团糟……现在看起来更像Ruby ...)


3

Python 3,63字节

这是一个匿名lambda函数,它使用字符串作为参数,并返回其块状信息。

lambda n:~-len(n)and sum(x!=y for x,y in zip(n,n[1:]))/~-len(n)

要使用它,请给它命名并调用它。

f=lambda n:~-len(n)and sum(x!=y for x,y in zip(n,n[1:]))/~-len(n)
f("Peanut Butter") -> 0.08333333333333333
f("!")             -> 0
f("")              -> -0.0

除了匿名功能,您可以使用:def f(n):,其字符数与完全相同lambda n:。这样就无需为函数命名。
特里斯坦·里德

@TristanReid def f(n):还需要return
Sp3000

糟糕!好的收获-我是Codegolf的新手,我应该假设对此有更多考虑并在本地进行测试。道歉!
特里斯坦·里德

3

Python 3,52个字节

lambda s:sum(map(str.__ne__,s,s[1:]))/(len(s)-1or 1)

这将计算出块状性,并输出-0.0空字符串。如果不喜欢负零,则可以随时用一个额外的字节来解决:

lambda s:sum(map(str.__ne__,s,s[1:]))/max(len(s)-1,1)

2

Haskell,64个字节

f[]=1
f[_]=1
f x=sum[1|(a,b)<-zip=<<tail$x,a==b]/(sum(x>>[1])-1)

输出平滑度。例如f "Peanut Butter"-> 8.333333333333333e-2

怎么运行的:

f[]=1                               -- special case: empty list
f[_]=1                              -- special case: one element list

f x=                                -- x has at least two elements
         (a,b)<-zip=<<tail$x        -- for every pair (a,b), drawn from zipping x with the tail of itself
                            ,a==b   -- where a equals b
      [1|                        ]  -- take a 1
   sum                              -- and sum it
              /                     -- divide  by
                   (x>>[1])         -- map each element of x to 1
               sum                  -- sum it
                           -1       -- and subtract 1

sum(x>>[1])是x的长度,但是因为Haskell的强类型系统要求将小数提供给/,所以我不能使用length返回整数的小数。通过将整数转换为小数fromInteger$length x太长了。


您是否尝试过使用Rational
recursion.ninja

@ recursion.ninja:不,我不是因为我认为18字节import Data.Ratio太昂贵了。
nimi 2015年

2

JavaScript(ES6),55个字节

平滑度,56个字节

f=x=>(z=x.match(/(.)(?=\1)/g))?z.length/--x.length:+!x[1]

块,55字节

f=x=>(z=x.match(/(.)(?!\1)/g))&&--z.length/--x.length||0

演示版

计算平滑度,因为这是我更喜欢的。目前仅适用于Firefox,因为它是ES6。

f=x=>(z=x.match(/(.)(?=\1)/g))?z.length/--x.length:+!x[1]

O.innerHTML += f('Peanut Butter') + '\n';
O.innerHTML += f('chUnky') + '\n';
O.innerHTML += f('sssmmsss') + '\n';
O.innerHTML += f('999') + '\n';
O.innerHTML += f('AA') + '\n';
O.innerHTML += f('Aa') + '\n';
O.innerHTML += f('!') + '\n';
O.innerHTML += f('') + '\n';
<pre id=O></pre>


2

KDB(Q),30

返回平滑度。

{1^sum[x]%count x:1_(=':)(),x}

说明

                         (),x    / ensure input is always list
                x:1_(=':)        / check equalness to prev char and reassign to x
   sum[x]%count                  / sum equalness divide by count N-1
 1^                              / fill null with 1 since empty/single char will result in null
{                             }  / lamdba

测试

q){1^sum[x]%count x}1_(=':)(),x}"Peanut Butter"
0.08333333
q){1^sum[x]%count x:1_(=':)(),x}"sssmmsss"
0.7142857
q){1^sum[x]%count x:1_(=':)(),x}"Aa"
0f
q){1^sum[x]%count x:1_(=':)(),x}"aa"
1f
q){1^sum[x]%count x:1_(=':)(),x}"chUnky"
0f
q){1^sum[x]%count x:1_(=':)(),x}"!"
1f
q){1^sum[x]%count x:1_(=':)(),x}""
1f

2

红宝石69 66字节

->s{(c=s.chars.each_cons(2).count{|x,y|x!=y}.to_f/~-s.size)>0?c:0}

在线尝试!

从IMP的评论中删除了几个字节。此外,使用Ruby的即将到来的2.7.0版本有可能通过更换节省一些字节|x,y|x!=y@1!=@2


如果将.to_f/~-s.sizec 移到c的赋值中,则可以使用三元操作f=->s{(c=s.chars.each_cons(2).count{|x,y|x!=y}.to_f/~-s.size)>0?c:0}
删除

另外,您需要f=吗?我不是100%遵守有关规则。挑战在于,您可以返回一个带有字符串的函数,即稳定的lambda。
IMP1

同样,虽然Perl答案的长度可能相同,但并没有100%的粗大程度与答案相同。
IMP1

@ IMP1谢谢:)
daniero

1

Python 3,69个字节

尚无人发布Python解决方案,因此这是“简单性”功能的相当简单的实现。它在length的字符串上短路1并打印0(这是一个整数,而不是浮点数,但根据规则似乎是允许的)。

在空字符串上,输出-0.0而不是0.0。可以说这可以被认为是可以接受的,作为-0.0 == 0 == 0.0return True

def c(s):l=len(s)-1;return l and sum(s[i]!=s[i+1]for i in range(l))/l

例子:

>>> c(''); c('a'); c('aaa'); c("Peanut Butter")
-0.0
0
0.0
0.916666666667
>>> -0.0 == 0 == 0.0
True

(Python 3用于其默认的浮点除法。)


1

C,83字节

float f(char*s){int a=0,b=0;if(*s)while(s[++a])b+=s[a]!=s[a-1];return--a?1.*b/a:b;}

返回矮胖的函数。

说明

float f(char *s) {

接受一个C字符串,并返回一个浮点数(双倍有效,但更多字符)。

int a=0, b=0;

计数器- a用于总计对,b用于不匹配对。使用int限制了字符串的“任意长度”,但这只是对要求的轻微违反,我将不对其进行修复。

if (*s)

特殊情况下为空字符串-将两个计数器都保留为零。

    while (s[++a])

非空字符串-以预递增的方式遍历它(因此,第一次通过循环,s[a]将是第二个字符。如果该字符串只有一个字符,则将不输入循环主体,a将为1。

        b += s[a]!=s[a-1];

如果当前字符与前一个字符不同,请增加b

return --a ? 1.*b/a : b;
}

循环之后,存在三种可能性:空输入为'a == 0,b == 0',单字符输入为'a == 1,b == 0'或'a> 1,b> = 0'用于多字符输入。我们从中减去1 a?运算符是一个序列点,所以我们很安全),如果它为零,则有第二种情况,因此应返回零。否则,b/a这就是我们想要的,但是我们必须首先提升b为浮点类型,否则我们将获得整数除法。对于空字符串,我们将以负零结尾,但是规则不允许这样做。

测试:

#include <stdio.h>
int main(int argc, char **argv)
{
    while (*++argv)
        printf("%.6f %s\n", f(*argv), *argv);
}

这使:

./chunky 'Peanut Butter' chUnky sssmmsss 999 AA Aa '!' ''
0.916667 Peanut Butter
1.000000 chUnky
0.285714 sssmmsss
0.000000 999
0.000000 AA
1.000000 Aa
0.000000 !
-0.000000 

按要求。



使用编译器标志的66个字节(如果您喜欢这种事情)。编辑:我将其切换为gcc
vazt

1

Perl,69岁

函数返回的平滑度

sub f{($_)=@_;$s=s/(.)(?!\1)//sgr;chop;!$_||length($s)/length;}

说明

sub f {
    # read argument into $_
    ($_) = @_;

    # copy $_ to $s, removing any char not followed by itself
    # /s to handle newlines as all other characters
    $s = s/(.)(?!\1)//sgr;

     # reduce length by one (unless empty)
    chop;

    # $_ is empty (false) if length was 0 or 1
    # return 1 in that case, else number of pairs / new length
    !$_ || length($s)/length;
}

测验

printf "%.6f %s\n", f($a=$_), $a foreach (@ARGV);

0.083333 Peanut Butter
0.000000 chUnky
0.714286 sssmmsss
1.000000 999
1.000000 AA
0.000000 Aa
1.000000 !
1.000000 

1

Mathematica,73 72个字节

这并没有赢得任何规模,但很简单:

光滑度

N@Count[Differences@#,_Plus]/(Length@#-1)&@StringSplit[#,""]&

In[177]:= N@Count[Differences@#,_Plus]/(Length@#-1)&@StringSplit[#,""] &@"sssmmsss"

Out[177]= 0.285714

Length[#]-> Length@#保存笔画。消除N@并更改11.
hYPotenuser

@hYPotenuser是的。错过了。
rcollyer

1

GeL:76 73个字符

光滑度

@set{d;0}
?\P$1=@incr{d}
?=
\Z=@lua{c=@column -1\;return c<1and 1or $d/c}

样品运行:

bash-4.3$ for i in 'Peanut Butter' 'chUnky' 'sssmmsss' '999' 'AA' 'Aa' '!' ''; do
>     echo -n "$i -> "
>     echo -n "$i" | gel -f smooth.gel
>     echo
> done
Peanut Butter -> 0.083333333333333
chUnky -> 0
sssmmsss -> 0.71428571428571
999 -> 1
AA -> 1
Aa -> 0
! -> 1
 -> 1

(GeL = Gema + Lua绑定。好多了,但距离胜利还差得远。)

Gema:123120个字符

光滑度

@set{d;0}
?\P$1=@incr{d}
?=
\Z=@subst{\?\*=\?.\*;@cmpn{@column;1;10;10;@fill-right{00000;@div{$d0000;@sub{@column;1}}}}}

样品运行:

bash-4.3$ for i in 'Peanut Butter' 'chUnky' 'sssmmsss' '999' 'AA' 'Aa' '!' ''; do
>     echo -n "$i -> "
>     echo -n "$i" | gema -f smooth.gema
>     echo
> done
Peanut Butter -> 0.0833
chUnky -> 0.0000
sssmmsss -> 0.7142
999 -> 1.0000
AA -> 1.0000
Aa -> 0.0000
! -> 1.0
 -> 1.0

(更多的练习是我自己看看在没有浮点数支持和一般痛苦的算术支持的情况下用语言解决它的机会。第二行,尤其是\P序列,是纯魔术,最后一行是真实的折磨。)


1

Java 8,84 82字节

s->{float l=s.length()-1,S=s.split("(.)(?=\\1)").length-1;return l<1?1:S<1?0:S/l;}

输出平滑度。

在线尝试。

说明:

s->{                     // Method with String parameter and float return-type
  float l=s.length()-1,  //  Length of the input-String minus 1 (amount of pairs in total)
        S=s.split("(.)(?=\\1)").length-1;
                         //  Length of the input split by duplicated pairs (with lookahead)
  return l<1?            //  If the length of the input is either 0 or 1:
          1              //   Return 1
         :S<1?           //  Else-if `S` is -1 or 0:
          0              //   Return 0
         :               //  Else:
          S/l;}          //   Return duplicated pairs divided by the length-1


0

PowerShell,55个字节

光滑度

%{$s=$_;@([char[]]$s|?{$_-eq$a;$a=$_;$i++}).count/--$i}

在stdin中获取变量然后为其提供标识符似乎有点愚蠢,但是比拥有函数要快。


0

Python 3,61字节

计算大块:

f=lambda s: sum(a!=b for a,b in zip(s,s[1:]))/max(len(s)-1,1)


0

Ruby,63字节

输出块状。

f=->s{s.chars.each_cons(2).count{|x,y|x!=y}/[s.size-1.0,1].max}

与@daniero的解决方案类似,但通过直接除以字符串长度-1然后依赖.count为零(长度为0&1字符串)而略有缩短(.max确保我不会除以0或-1)。


0

Mathematica,107个字节

通过取每个有向图及其反面之间的Levenshtein距离的一半来计算粗略度。

f[s_]:=.5EditDistance@@{#,StringReverse@#}&/@StringCases[s,_~Repeated~{2},Overlaps->All]//Total@#/Length[#]&

如果您想要一个确切的理性答案,请删除.5/2在最后一个词前放置一个&,不收取任何罚款。程序本身具有块状103/106,或约.972。

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.