弄清楚这些字符串


42

受此评论链启发...

我想enklact摆脱挑战,但是我不能...

@ETHproductions 进行编码(v):使用包含唯一元素的小节来实现查找表。


粘贴是压缩查找表的一种非常有用的方法。例如,假设您具有以下颜色列表:

red
green
blue
yellow
purple
orange

如果您希望能够将一种颜色用作输入并返回其在此列表中的索引,那么显然有一种简单的方法:

["red", "green", "blue", "yellow", "purple", "orange"].index(input())

但是有一种方法可以减少字节数:

"rgbypo".index(input()[0])

之所以有效,是因为每个字符串的第一个(或第0个)索引都是唯一的。这个例子很明显,但有时会更难一些。如果我们想为此列表创建查找表怎么办?

Sweet Onion Chicken Teriyaki
Oven Roasted Chicken
Turkey Breast
Italian BMT
Tuna
Black Forest Ham
Meatball Marinara

在这种情况下,我们不能这样做:

"SOTITBM".index(input()[0])

因为有两个不同的输入以a开头'T',即“ Tuna”和“ Turkey”。我们必须看一个不同的索引。如果查看每个字符串的第4个索引,您会注意到它们都是唯一的。所以我们可以做...

"enklact".index(input()[3])

在这种情况下,“字符串”是“字符串”。

这导致我们面对今天的挑战...

给定字符串列表,请返回任何有效的字符串。换句话说,给定一个字符串列表,返回任何新的字符串,其中每个字母都是唯一的,并且该字符串是通过连接每个字符串的第i个字母而形成的。

如果没有有效的字符串,则您的提交必须返回一个空字符串或一致的伪造值。与往常一样,允许使用功能或完整程序,并且输入/输出格式是允许的(在合理范围内)。

每个字符串将仅包含可打印的ASCII,并且此挑战区分大小写。

这是,因此请尝试使用您选择的语言编写最短的程序!

测试用例

Input:
Programming
Puzzles
Code
Golf

Output (any one of these):
"ozdl"
"gzef"


Input:
the quick
brown fox
jumped over
lazy dogs

Output:
"tbjl"
"hrua"
"eomz"
" wpy"
"qne "
"if o"
"kxvs"

Note that "u dd" and "coog" are not valid.


Input:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Output:
""


Input:
AbC
aBc
bbC

Output:
"Aab"


Input:
@#$%^_
Hello_World
How are you?

Output:
"#eo"
"$lw"
"%l "
"^oa"


Input:
a
ab
ac

Output:
""

我们可以返回有效字符串列表吗?
LyricLy

@LyricLy Hmm,现在我考虑一下,那会更有意义。但是,由于已经有了答案,并且返回第一个答案并不需要太多,所以我要说不,它应该是任何有效的字符串。
DJMcMayhem

我们可以保证所有输入的字符串都不为空吗?
musicman523

6
一致的假值可以是一致类型的错误吗?
Stewie Griffin

2
对不起,但我认为正确的动词是过动的
暴民埃里克(Erik the Outgolfer)'18年

Answers:


8

Python3,59个字节

lambda l:{len({*d}):''.join(d)for d in zip(*l)}.get(len(l))

返回带有enklact的字符串,否则返回None


8

Python 2中68个 67 61字节

lambda a:`{0:j for j in zip(*a)if len(set(j))==len(j)}`[6::5]

在线尝试!

改进措施

  • Jo King从68字节增加到67字节
  • Lynn从66到65字节

如果输出不必是字符串:

Python 3,49个字节

lambda a:[j for j in zip(*a)if len({*j})==len(j)]

在线尝试!



@JoKing优雅并实现。
尼尔,

我认为max(`j`[2::5]for j in[""]+zip(*a)if len(set(j))==len(j))可以节省一个字节。
林恩

@琳恩感谢和更新。
尼尔

7

视网膜43 32字节

+/^(.).+^\1|^$/ms&m`^.

|""Lm`^.

在线尝试!编辑:由于@MartinEnder,节省了11个字节。说明:

+

输入更改时重复...

/^(.).+^\1|^$/ms&

...仅当一行为空或两行以相同字符开头时...

m`^.

...删除每行的第一个字符。因此,如果a)所有行以不同的字符开头,则重复停止,在这种情况下,条件失败且输入内容不变,或者b)至少一行变为空,在这种情况下,所有字符最终都被删除,此时输入停止更改。

|""L`^.

收集每一行的第一个字符。(如果没有解决方案,则上面的循环将删除所有内容,并且没有任何可收集的内容。)


正则表达式选项还采用了正则表达式修饰符(通过在结束定界符之后直接编写正则表达式修饰符):tio.run/##K0otycxLNPz/…
Martin Ender,

实际上,这使您完全摆脱了第二阶段:tio.run / ## K0otycxLNPz / X1s /…(某种程度上不能m在此处应用组,看起来条件阶段不会传播该选项)。
马丁·恩德

嗯,当然可以循环条件循环而不是条件循环,这可以解决您的第一个版本中的无限循环错误。很整齐!
尼尔,

5

Haskell,71个字节

f x|elem""x=""|y<-head<$>x,and[filter(==a)y==[a]|a<-y]=y|1<2=f$tail<$>x

在线尝试!

BMO使用any null x→ 保存3个字节elem""x

ØrjanJohansen用sum[1|b<-y,a==b]<2→ 保存了一个字节filter(==a)[y]==[a]

说明

f x|elem""x=""                      -- Once any of the strings is empty, return "".
   |y<-head<$>x                     -- Otherwise, let y be all the first letters...
   ,and[                 |a<-y]     -- If, for all a in y,
        filter(==a)y==[a]           -- a occurs just once in y:
                               =y   -- return y.
   |1<2=f$tail<$>x                  -- Else, chop off all the first letters and recurse.

如果Prelude.head: empty list在没有解决方法的情况下抛出错误()可以,|elem""x=""则可以擦除61个字节


1
更短的测试:filter(==a)y==[a]
与Orjan约翰森

4

Ruby,38个字节

->x,*y{x.zip(*y).find{|z|z==z-[p]|[]}}

在线尝试!

感谢GB指出错误。


如果没有匹配项且第一个字符串不是最短字符串,则失败。
GB

@GB请您举个例子吗?我根据您的描述修改了我的上一个测试,并且该测试有效。
Kirill L.

尝试[“ abc”,“ ac”,“ acd”]
GB

现在我明白了,你是对的。应该是固定的。
Kirill L.

4

Pyth,6个字节

>1{I#C

测试套件。

输出是一个单例列表,默认情况下允许;列表[] (空列表,falsy)的情况下,返回字符串不能enklactified

说明

> 1 {I#C –完整程序。
     C –移调输入,裁剪缺失。
    # - 过滤:
  {I –重复数据删除不变。
> 1 –在Python中切片为1. list [:1]。

Pyth,5个字节

如果将崩溃视为虚假值,这将是有效的。

h{I#C

测试套件。


3

Haskell76 74字节

f t=last$"":(id=<<foldr(zipWith(#))([[]]<$t)t)
x#[s]=[x:s|all(/=x)s]
x#e=e

在线尝试!返回最后一个有效的查询字符串,如果不存在则返回一个空字符串。


71 69字节

如果将一致的异常作为虚假值抛出:

f t=head$id=<<foldr(zipWith(#))([[]]<$t)t
x#[s]=[x:s|all(/=x)s]
x#e=e

在线尝试!empty list如果找不到字符串,则引发异常,否则返回第一个有效字符串。

-2个字节,感谢ØrjanJohansen


1
notElem x 可以缩短为all(/=x)
与Orjan约翰森

2

果冻,7个字节

z0Q€fZḢ

如果无法字符串化,则返回整数0

在线尝试!

这个怎么运作

z0Q€fZḢ  Main link. Argument: A (string array)

z0       Zip/transpose, filling shorter rows with 0.
  Q€     Unique each deduplicate resulting string.
     Z   Zip/transpose, without using a filler.
    f    Filter; keep only string that appear in the results to both sides.
      Ḣ  Head; extract the first string. Returns 0 if the array is empty.


2

Stax9 8 字节

åτIⁿs↓µg

运行并调试

说明(未包装):

M{c0-u=}j Full program, implicit input
          e.g. ["Programming", "Puzzles", "Code", "Golf"]
M         Transpose
                ["PPCG", "ruoo", "ozdl", "gzef", "rl\0\0", "ae\0\0", "ms\0\0", "m\0\0\0", "i\0\0\0", "n\0\0\0", "g\0\0\0"]
 {     }j Find first matching element:
            e.g. "PPCG"
  c0-       Copy and remove zero bytes (padding)
                 "PPCG" "PPCG"
     u      Unique
                 "PPCG" "PCG"
      =     Check if equal:
                 1
          First matching here: "ozdl". If none is found, the stack is empty
          Implicit output if anything on stack

2

R,127字节

function(S,s=sapply(S,substring,x<-1:max(nchar(S)+1),x))cat(rbind(s[!apply(s,1,anyDuplicated)&!rowSums(s==""),],"")[1,],sep="")

在线尝试!

sapply通常matrix在所有条件length(FUN(X[[i]]))都相等时返回a ,除了when时length(FUN(X[[i]]))==1,在这种情况下会返回a vector。因此,为了使用矩阵运算,我们必须substring比保证a还要进一步matrix,这就是为什么要x扩展到的原因max(nchar(S)+1)

然后,我们将筛选没有重复且没有空字符串的行。由于我们只能返回一个字符串,因此我们取第一个字符串,只是当没有行符合条件时,会抛出错误,因此我们在末尾追加了一行""

然后我们打印出enklact修饰后的字符串或空字符串。


2

[R 116个 107 95字节

R + pryr

pryr::f(for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
break}))

在线尝试!

R基

function(v)for(i in 1:min(nchar(v)))`if`(anyDuplicated(t<-substr(v,i,i)),0,{cat(t,sep="")
v=0})

在线尝试!

这两个变量节省了9个字节,这要归功于Giuseppe

说明:

这有效地将向量v中的所有字符串都截断为最短的长度,并迭代后续的索引。然后检查所选字母中是否有重复项,如果没有,将它们粘贴在一起并用打印cat。如果所有索引返回重复的结果,则将输出空字符串。
全部包裹在一个匿名pryr函数中break以暂停循环,或将R函数清零以中断循环。


1
好东西!这可以golfed到107个字节R+pryr或者107个字节在碱R.
朱塞佩

2

Japt,9个字节

将输入作为字符数组的数组,返回字符数组或 undefined

y æ_f eZâ

尝试一下(在程序的开头添加新行,并使用代码qR mq将输入作为换行符分隔的字符串,以节省创建数组的麻烦。)


说明

y             :Transpose
  æ_          :Pass each array Z through a function and return the first that returns true
    f         :  Filter nulls (used for padding when transposing)
      e       :  Test for equality with
       Zâ     :  Z deduplicated

在阅读您的解决方案之前,我尝试了挑战,并得到了几乎相同的解决方案:z æ_¬eZ¬â
Nit

除了输入格式外,完全相同。
毛茸茸的

2

05AB1E,7个字节

øʒDÙQ}н

在线尝试!

说明

ø        # Zip the input array
 ʒ   }   # Filter by ...
  DÙQ    # ... an entry is equal to itself deduplicated
      н  # Take the first element

1

Python 3,75个字节

def f(t):c=[s.pop(0)for s in t];return all(t)and(f(t),c)[len(t)==len({*c})]

在字符列表而不是字符串上操作。如果不存在有效的字符串,则返回False。

在线尝试!


我认为这是递归的,除非f=字节数中包括,否则它将使其无效。
LyricLy

@LyricLy Fixed :)
musicman523 '18

1

C(gcc),161字节

f(s,i)char**s;{char**t,a[255],*u=a;for(i=0;memset(a,0,255),u&&~i;i+=!!~i&&u)for(t=s;(u=u?*t++:0)&&~(i=u[i]?i:-1)&&!a[u[i]]++;);while(~i&&(u=*s++))putchar(u[i]);}

在线尝试!

测试每个字符位置是否重复,如果检测到重复则跳过;一直持续到最短的字符串结束为止。不幸的是,它仅是ASCII:DBCS / UTF-8字符串严重破坏了此功能!



1

Japt,12个字节

返回undefined非enklactic字符串。

y ·æ_¬n ä¦ e

在线尝试!

说明:

y ·æ_¬n ä¦ e
y             // Split the input at newlines and transpose
  ·           // Join on newlines 
   æ_         // Return the first item that returns truthy when ran through:
     ¬n       //   Sort
        ä¦    //   Reduce with !=
           e  //   All items are truthy (unique)

通过将输入作为字符数组的数组并切掉两个splits,您应该能够节省2个字节。
毛茸茸的

1

Wolfram语言(Mathematica),54个字节

#&@@Select[PadRight@#,#~FreeQ~0&&Union@#==Sort@#&]&

在线尝试!

将字符列表作为输入,返回字符列表。包含U + F3C7,对应于“转置”运算符。

#1当没有合适的字符串时,返回并抛出一堆可忽略的错误。

说明:

PadRight@#

填充输入,以使每个“字符串”(字符列表)具有相同的长度。这将附加整数0s(而不是字符串"0"s)。然后转置。

Select[ ... ,#~FreeQ~0&&Union@#==Sort@#&]

选择其中没有整数0并且具有所有唯一字符的字符串。

#&@@

获取第一个。


1

JavaScript(ES6),66个字节

返回字符串或undefined不存在解决方案。

f=(a,i=0)=>a.every(s=>(o[k+=c=s[i],c]^=1)&&c,o=k=[])?k:c&&f(a,i+1)

在线尝试!

已评论

f = (           // f = recursive function taking:
  a,            //   a[] = input array
  i = 0         //   i   = pointer
) =>            //
  a.every(s =>  // for each string s in a[]:
    (o[k +=     //   append to the key string k
      c = s[i], //   the character c at position i in s
      c] ^= 1   //   and toggle o[c] (undefined -> 1 -> 0)
    ) && c,     //   additionally, make sure that c is defined
    o = k = []  //   start with o = k = empty array
  ) ?           // every() is true if all characters were distinct and defined:
    k           //   in which case we return k
  :             // else:
    c &&        //   provided that every() didn't fail because of an undefined character,
    f(a, i + 1) //   try again at the next position

1

木炭23 21字节

-2个字节,感谢@Neil

§ΦE⌊EθLι⭆θ§λι⬤ι⁼¹№ιλ⁰

在线尝试!


嗯,什么时候a)q永远不再是字符串b)StringMap开始在非字符串上工作?无论如何,您Range是不必要的,可节省2个字节。
尼尔,

@Neil a)当我添加数组/对象输入b)> _>我不确定。大概在我修复while循环的时候(对不起,忘了提及其中任何一个)
(仅ASCII

1

外壳,9个字节

ḟS=UḞz:∞ø

在线尝试!

说明

fS=UḞz:∞ø
    Ḟz:∞ø  Transpose the input dropping characters of longer strings
    Ḟ        Fold right
     z:      Zip with prepend
       ∞ø    Infinite list of empty lists
ḟS=U       Find the first string without duplicates, returns an empty string if none
ḟ            Return first value satisfying predicate
  =          Equal
 S U         to itself with duplicates removed

使用←ġLTover Ḟz:∞ø应该节省一个字节。
ბიმო

1

视网膜81 56字节

m`$
$.=*£¢
N$`.
$.%`
¶

~`(.*?¢)+
L`.{$#1}
A`(.).*\1|£|¢

在线尝试!

-25个字节,感谢@Neil


在视网膜中转置矩形文本非常困难。


我希望我知道执行矩形转置的更好方法,但与此同时,节省了25个字节
尼尔

@Neil Ahh ...评估阶段。我总是忘记视网膜1.0具有所有这些很酷的新功能
TwiNight

1

Perl 6,27个字节

{([Z] $_).first:{.Set==$_}}

在线尝试!

看到ruby版本已被支持后,我复制了该方法并使用了字符列表,而不是字符串。我不喜欢

我的较旧且更正确的提交如下:

Perl 6、38个字节

拆分,压缩,检查唯一性,加入。

{[~] ([Z] @_>>.comb).first:{.Set==$_}}

在线尝试!


1

C(GCC) 121个 113 110字节

i;d;f(s)char**s;{char**_=s,x[255]={0},y[99]={0};for(d=i=0;*_;)d+=x[y[i++]=*(*_++)++]++;d=d?*x?0:f(s):puts(y);}

在线尝试!

不打高尔夫球

void enklactify(char *strings[]) {
    int quit = 0;
    while (!quit) {
        char **arg = strings;      // current row
        int exists[255] = {0};     // which characters exist in the column
        char output[99] = {0};     // will hold output string
        int index = 0;             // where to insert in output
        int duplicates = 0;        // have we found any duplicates?
        while (*arg != NULL) {
            char *word = *arg;     // current word
            char first = *word;    // first letter of current word
            if (exists[first])
                duplicates = 1;    // we found a duplicate
            exists[first] = 1;     // mark it as in our string
            output[index] = first; // add it to our output
            index++;
            (*arg)++;              // advances the current word to the next
                                   // character by reference (chops first char)
            arg++;                 // advance to next whole argument
        }

        if (!duplicates) {         // This is a valid solution
            puts(output);
            quit = 1;
        }

        if (exists[0]) {           // We hit the null terminator of one of the
                                   // input strings, so we failed
            quit = 1;
        }
    }
}

-3多亏了ceilingcat

这滥用了仅向C中的字符串指针加1以获取字符串的“尾巴”的功能。主要的字节保存器是:

  • d+=x[y[i++]=*(*_)++]++其中附加的第一串的第一字符_y,前进的第一串_,以除去其第一个字符,加x在该字符输入d,和增量所述x条目
  • q=d?*x:puts(y)当设置为非零值时,y如果if d为非零,则打印;如果的第一个元素为非零,则打印为非零(如果我们位于一个字符串的末尾,则该元素将为非零。零)qqx

编辑:通过从while循环切换到递归尾部调用并从for循环中删除括号,可以剃除字节。


推荐for(d=i=0;*_;)替代for(d=0,i=0;*_;++_)*(*_++)++]++;d=d?!*x*f(s)取代*(*_)++]++;d=d?*x?0:f(s)
ceilingcat

0

Pyth,13个字节

e+kf{IT@.TQ.t

在这里尝试

e+kf{IT@.TQ.t
           .tQ   Transpose the (implicit) input with padding.
        .TQ      Transpose the input without padding.
       @         Take the strings in both.
   f{IT          Find the ones that have no duplicates.
e+k              Get the last, or an empty string.

1
似乎返回所有有效字符串的列表是无效的。
LyricLy

@LyricLy固定。
助记符

0

红色,139字节

func[b][m: length? first b foreach a b[m: min m length? a]repeat n m[c: copy[]foreach a b[append c a/(n)]if c = unique c[return rejoin c]]]

在线尝试!

说明:

将输入作为字符串块(列表)。返回enklaction字符串或none以其他方式。

f: func[b][
    m: length? first b                   ; the minimal length of the first string  
    foreach a b[m: min m length? a]      ; find the minimal length of all strings
    repeat n m[                          ; limit the search to the minimal length
        c: copy[]                        ; an empty block  
        foreach a b[append c a/(n)]      ; for each string append the current char
        if c = unique c[return rejoin c] ; if all chars are unique, return the block
    ]  
]

0

Röda80 77字节

f a{a|seq 0,#_|try{{|i|a|[_[i:i+1]]|orderedUniq|concat|[_]if[#_1=#a]}_|head}}

在线尝试!

-1字节归功于Cows quack

说明:

f a{
  a|         /* Push the strings in a to the stream */
             /* For each string (_): */
  seq 0,#_|     /* Push a range from 0 to the length of _ to the stream */
  try{       /* Ignore errors during the following block */
    {|i|        /* For each i in the stream: */
      a|           /* Push strings in a to the stream */
      [_[i:i+1]]|  /* For each string, push the ith character to the stream */
      orderedUniq| /* Remove duplicate characters */
      concat|      /* Join the characters into a string */
      [_]if        /* Push the string to the stream if */
      [#_1=#a]     /* Its length is the length of a */
    }_|
    head        /* Take the first string in the stream and return it */
  }
}

所述try关键字被用于关闭如果发生的错误i比最小的字符串的长度大a,或无应答和head导致错误。


您可以删除括号seq以保存一个字节
Kritixi Lithos

@Cowsquack谢谢!
fergusq '18年

0

Java 10,106个字节

a->{for(int i=0;;i++){var r="";for(var s:a)r+=s[i];if(r.length()==r.chars().distinct().count())return r;}}

如果找不到解决方案,将给出错误而不是返回空的String。输入是一个字符矩阵。

在线尝试。

说明:

a->{                  // Method with character-matrix parameter and String return-type
  for(int i=0;;i++){  //  Loop `i` upwards
    var r="";         //   Result-String, starting empty
    for(var s:a)      //   Loop over the character-arrays of the input
      r+=s[i];        //    And append every `i`'th character to `r`
    if(r.length()==r.chars().distinct().count())
                      //   If `r` only contains unique characters
      return r;}}     //    Return `r` as result

OP似乎不想允许错误,尽管公认的是从未将其放在帖子中。
与Orjan约翰森

0

Clojure,59个字节

#(for[s(apply map list %):when(=(count(set s))(count %))]s)

返回字符列表。


0

APL + WIN,35 33字节

多亏了Adám,节省了2个字节

提示将文本行作为字符矩阵:

⊃((↑⍴¨a)=+/¨((a⍳¨a)=⍳¨⍴¨a))/a←,⌿⎕

在线尝试!由Dyalog Classic提供

说明:

a←,⌿⎕ prompts for input and creates a nested vector of the input matrix columns

((a⍳¨a)=⍳¨⍴¨a) creates a binary vector for each nested element with a 1 for each unique element

((↑⍴¨a)=+/¨ sums each binary vector and compares to number of characters in each element

(...)/a←⊂[1]⎕ selects only those elements where number of uniques = column length

⊃ converts nested vector back to a matrix of each valid enklaction string 

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.