紧密的词


22

介绍

根据Rand Al'Thor在《 Puzzling SE》中的帖子,紧密结合的单词是包含三个字母连续字母(任意顺序)的任何单词。

教育雾角歌舞表演之类的词都被认为是紧密结合的词,而学习克拉克森表演等词则不是紧密结合的词。

挑战

面临的挑战是对一个程序进行代码处理,使其能够将单个单词作为输入(假设所有目的和目的都为小写),并返回列出所有连续字母集(如果有的话)的输出(如果有的话)。是紧密词,如果不是紧密词,则输出为空。

例子

Input: education
Output: cde

Input: foghorn
Output: fgh

Input: cabaret
Output: abc

Input: hijacking
Output: ghi, hij, ijk

Input: pneumonia
Output: mno, nop

Input: klaxon
Output: <<no output>>

Input: perform
Output: <<no output>>

Input: learning
Output: <<no output>>

规则

  1. 尽管将输入假定为单个小写单词,而将输出假定为小写,但是输出的性质将根据您选择的编码语言而有所不同。请选择最适合挑战性质的输出形式,无论是STDOUT,文件输出,数组等。
  2. 因为这是代码高尔夫,所以肯定会有最少的字节数。
  3. 没有愚蠢的漏洞
  4. 我将不接受具有非字母顺序的连续字母的答案...因此,例如,cab不会被认为是合适的输出cabaret
  5. 特别说明,虽然“三胞胎”不一定必须按字母顺序排列,但是三胞胎中的字符必须是...,因此,例如,对于“表演”一词,mno,nop将接受输出,一如既往nop,mno。在“劫持”一词的情况下ghihij和的三元组ijk可以通过六种方式排列在一个列表中,并且所有六个排列都可以作为输出。

除此之外,您还可以打高尔夫!


输出是否可以是一个二维char数组,每列中每组三个连续的字母?
路易斯·门多

@LuisMendo您能给我一个例子让我看到它吗?
WallyWest'9

尝试我的代码时不要使用final,!而要使用另一个词,因为当前的词给出的结果是相同的:-)
Luis Mendo

@LuisMendo是MATL专栏专业还是什么?
Maltysen

1
以元组数组的格式输出是否pneumonia可以,即的输出可以是[('m','n','o'),('n','o','p')])
R. Kap

Answers:


8

05AB1E7 6 5字节

码:

3ãAŒÃ

说明:

3ã      # Cartesian product × 3 with input
  AŒ    # All substrings of the alphabet
    Ã   # Setwise intersection

使用CP-1252编码。在线尝试!


这真是天才……我将不得不尝试创造一种挑战,将这种语言推向极限……;)
WallyWest 2016年

10

Python 3.5,68个字节

w=input()
a=0
while 1:s='%c'*3%(a,a+1,a+2);a+=1;{*s}-{*w}or print(s)

打印输出字符串,并在字符值太大时以错误终止。

生成三个连续的所有字符串,并打印作为输入单词子集的字符串。


8

Pyth- 11 10 8 7个字节

超级蛮力法。

@^z3.:G

测试套件

@            Setwise intersection, finds common strings between the two lists
 ^           Cartesian product
  z          Input
  3          Of length 3
 .:          Substrings. Without second input finds all substrings which is ok
  G          Lowercase aphabet

7

果冻,7 个字节

ØaẆfṗ3$

这是一个单子链接。在线尝试!

怎么运行的

ØaẆfṗ3$  Monadic link. Argument: s (string)

Øa       Yield the lowercase alphabet, i.e., a := "abcdefghijklmnopqrstuvwxyz".
  Ẇ      Window; yields all substrings of a.
      $  Combine the two links to the left into a monadic chain.
    ṗ3   Take the third Cartesian power of s, yielding all combinations of three
         characters that can be formed from the letters in s.
   f     Filter; keep only those substrings of a that appear in the Cart. power.

7

JavaScript(ES6),95 90字节

f=
s=>[...s].map(c=>a[parseInt(c,36)]=c,a=[])&&a.map((c,i)=>c+a[i+1]+a[i+2]).filter(c=>!c[3])
;
<input oninput="o.textContent=f(this.value).join`, `"><div id=o>

缺少的值串联为undefined,因此生成的字符串包含大于3个字符。我!c[3]从@ETHproductions 借来的技巧来节省5个字节。


2
巧合的undefined是,这个词很
贴切

为什么要parseInt(c,36)代替c.charCodeAt()
Titus

@Titus我想这没什么区别,我只是习惯于parseInt在代码高尔夫中使用。
尼尔,

4

Python 3.5,78个字节

s={*input()}
for c in s:o=ord(c);a=chr(o-2);b=chr(o-1);s>{a,b}and print(a+b+c)

4

PHP,100字节

for($a="abc",$i=98;$i<123;$a=substr($a,1).chr(++$i))if(strstr(count_chars($argv[1],3),$a))echo"$a,";

将输入作为命令行参数;打印尾随逗号。与运行-r


1
for($s=join(range(Z,z));$a=substr($s,++$i,3);)是创建$ a的较短方法。它当然会检查一堆标点符号以及一些2个字符的序列,但是由于输入仅是小写字母,因此它要求找到3个很好的字符。
user59178

for($a="ab“,$ i = 98; $ i <123;)!strstr(count_chars($ argv [1],3),$ a = substr($ a,1).chr(++ $ i))?: print “$ A”;`节省2个字节非常好的方式,我试图在PHP等方法,但不能达到你的代码的字节我不知道,如果你需要的逗号后面输入一个空格。
约尔格Hülsermann

4

C,175个 174字节

main(_,a,m,n)char**a;{char*s=a[1],*t=s;while(*++s)while(s>t&&(n=s[-1])>=*s){m=(*s^n)?*s:0;*s=n;*--s=m;!*t&&++t;}for(;t[1]&t[2];++t)*t==t[1]-1&&*t==t[2]-2&&printf("%.3s ",t);}

缩进:

main(_,a,m,n)char**a;
{
  char*s=a[1],*t=s;
  while(*++s)
    while(s>t&&(n=s[-1])>=*s){
      m=(*s^n)?*s:0;
      *s=n;
      *--s=m;
      !*t&&++t;
    }
  for(;t[1]&t[2];++t)
    *t==t[1]-1&&*t==t[2]-2&&printf("%.3s ",t);
}

在进行排序时,它将重复的值替换为0,这些0被排序到单词的开头。寻找连续的值就变得微不足道了。


1
欢迎光临本站!
DJMcMayhem

1
是的,欢迎使用PPCG!答案很出色,C不是最容易打高尔夫的人之一!
WallyWest'9

3

MATL,13字节

2Y23YCtjmAZ)!

在线尝试!

2Y2    % Push string of lowercase alphabet
3YC    % 2D char array with sliding blocks of size 3, each on a column
t      % Duplicate
j      % Take input
m      % Member function: true for elements of the 2D array that are in the input
A      % All: true for columns that consist of all true values
Z)     % Use as logical index into the columns of the 2D char array
!      % Transpose. Implicitly display

3

Haskell,48个字节

f w=filter(all(`elem`w))[take 3[c..]|c<-['a'..]]

生成三个连续字符的所有三元组,取那些仅在输入中使用字母的字符。


53个字节:

f w=filter(all(`elem`w))[[pred$pred c..c]|c<-['c'..]]

列表['c'..]包含从'c'开始的所有unicode字符。列表理解[[pred$pred c..c]|c<-['c'..]]将它们从头"abc"开始转换为3个连续字符的所有字符串。当采用最高unicode字符的后继字符时[pred$pred c..c][c..succ$succ c]为了避免出现错误,我们使用后退而不是前进。

对于仅在输入中使用字母的那些三元组,将对其进行过滤。


3

Perl,36个字节

包括+1的 -n

在STDIN上输入:

perl -nE 'join("",a..z)=~/[$_]{3}(?{say$&})^/' <<< "hijacking"

只是代码:

join("",a..z)=~/[$_]{3}(?{say$&})^/

3

T-SQL,153个字节

不得不对WallyWest的评论做出反应,因为它距上次TSQL回答已有很长时间了。答案部分受Brian J答案的启发

打高尔夫球:

USE MASTER
DECLARE @ varchar(max)='hijacking'

;WITH C as(SELECT distinct ascii(substring(@,number,1))z FROM spt_values)SELECT CHAR(C.z)+CHAR(D.z)+CHAR(E.z)FROM C,C D,C E WHERE c.z+1=d.z and d.z=e.z-1

小提琴

取消高尔夫:

USE MASTER -- can be left out if the master database is already being used
DECLARE @ varchar(max)='hijacking'

;WITH C as
(
  SELECT distinct ascii(substring(@,number,1))z
  FROM spt_values
)
SELECT CHAR(C.z)+CHAR(D.z)+CHAR(E.z)
FROM C,C D,C E
WHERE c.z+1=d.z and d.z=e.z-1

1
真聪明!甚至都不知道那个桌子。好消息是,单词长度不超过2048个字母!
Brian J

2

Haskell,63 60 52字节

f w=[x|x<-take 3<$>scanr(:)"_"['a'..],all(`elem`w)x]

用法示例:f "hijacking"-> ["ghi","hij","ijk"]

scanr(:)"_"['a'..]以所有unicode字符列表的'a'结尾构建一个列表,并以结尾'_',即["abcde...\1114111_", "bcde...\1114111_", "cde...\1114111_", ..., "\1114109\1114110\1114111_", "\1114110\1114111_", "\1114111_", "_"]。然后,每个字符串最多占用三个字符,并将其绑定到x。将所有x字母保留在输入参数中的所有位置w

编辑:@xnor保存3 7个字节。谢谢!


有谁知道我是否可以a:b:c:_使用@模式捕获列表的前三个元素?
nimi

我不知道@模式,但是您可以删除'z'上限并让它尝试所有字符。
xnor

捕获前三个元素确实很烦人。我所看到的最好的就是使用take并删除空字符串:f w=[x|x<-init$take 3<$>scanr(:)""['a'..],all(`elem`w)x]
xnor

@xnor:很好。我们可以scanr以“。” 开头。代替""并省略init$
nimi

2

T-SQL(SQL Server 2014),217字节

打高尔夫球

declare @ table(a char)declare @i int=1while @i<=len(@a)begin insert into @ values(SUBSTRING(@a,@i,1))set @i+=1 end select distinct t.a+u.a+v.a from @ t,@ u,@ v where ASCII(t.a)+1=ASCII(u.a)and ASCII(u.a)+1=ASCII(v.a)

用法

首先将变量@a声明为某种字符,然后像这样分配输入

declare @a varchar(max) = 'pneumoultramicroscopicsilicovolcanoconiosis'

我没有将声明作为我的代码的一部分,但是我没有找到用于输入的sql标准,所以我愿意更改我的计数

输出将为每个三元组一行,如果单词不是紧密编织,则无行

不打高尔夫球

declare @temp table ( letter char(1) ) -- table to hold each letter of the word

declare @i int = 1

while @i <= len(@input) -- split each letter, and each row in @temp will have one letter
begin
    insert into @temp values (SUBSTRING(@input, @i, 1))
    set @i = @i + 1
end

-- join the letters table to itself to get three letter triples, where the three are in adjacent increasing order
-- use distinct because there might be duplicates in the word
select distinct t1.letter + t2.letter + t3.letter
from @temp t1
cross apply @temp t2
cross apply @temp t3
where ASCII(t1.letter) + 1 = ASCII(t2.letter)
and ASCII(t2.letter) + 1 = ASCII(t3.letter)

看到我们正在处理在这种情况下执行所需的功能性声明后所需的代码,则不会计算该声明。自从我看到了挑战的SQL解决方案以来,辛苦了一段时间。做得好!
WallyWest'9

我已经将您的脚本打成185个字符,是未打高尔夫球的版本。你可能想看看我的答案以及
t-clausen.dk

2

R,220字节

我的解决方案非常简单。它遍历可能的三个字母组合,遍历并对照三个连续的字母检查输入字符串的字符,然后将它们添加到字符串中。然后仅在找到三个字母(c == 4)时才打印该字符串。

f<-function(w){if(nchar(w)>2){for(i in 1:24){
c<-1
t<-""
for(k in 1:3){for(j in 1:nchar(w)){if(substr(w,j,j)==intToUtf8(95+k+i)&c<4){
t<-paste(t,substr(w,j,j),sep="")
c<-c+1
break
}}}
if(c==4){print(paste(t))}}}}

输入输出

> f("education")
> [1] "cde"
> > f("foghorn")
> [1] "fgh"
> > f("cabaret")
> [1] "abc"
> > f("hijacking")
> [1] "ghi"
> [1] "hij"
> [1] "ijk"
> > f("pneumonia")
> [1] "mno"
> [1] "nop"
> > f("klaxon")
> > f("perform")
> > f("learning")
> > 

2

Python 3.5、114 111 88 80 79字节:

lambda X,W=[*map(chr,range(65,91))]:[i*({*X}>={*i})for i in zip(W,W[1:],W[2:])]

匿名lambda函数。将输入作为大写字符串,并输出一个元组数组,其中元组由三个大写字符填充,代表3输入中出现的所有连续字母集。例如,

[(), (), (), (), (), (), ('G', 'H', 'I'), ('H', 'I', 'J'), ('I', 'J', 'K'), (), (), (), (), (), (), (), (), (), (), (), (), (), ()]

将作为输入的输出HIJACKING。OP 已确认此输出格式可以。因此只有唯一的大写输入格式。但是,如果你想在输入只有小写,只需更换range(65,91)range(97,123),多加一个字节。

重复使用所有测试用例!

说明:

基本上,这里发生的是:

  1. W使用创建列表,W=[*map(chr,range(65,91))]其中包含英语字母表中的所有大写字母。因此,始终需要大写输入。

  2. 对于i列表中的每个元组,我们将称之为U,其中包含所有三个连续的字母元组,即:

    U=[('A','B','C'),('B','C','D'),('C','D','E'),...]
    

    通过创建zip(W,W[1:],W[2:]),每个i被完全添加到输出列表只要在该组版本中的所有元素i{*i})是在输入的设定版本X{*X}),即{*X}>={*i},即X是一个超集i。否则,i())的空白版本将添加到列表中。

  3. 一旦所有元组都已通过并完全添加了匹配项,该列表将作为最终输出返回。


2

Scala,59个字节

(s:Set[Char])=>'a'to'z'sliding 3 filter{_.toSet subsetOf s}

取消高尔夫:

(s:Set[Char]) => ('a' to 'z').sliding(3).filter{threeChars => threeChars.toSet.subsetOf(s)}

说明:

(s:Set[Char])=>             //define a function with a Set of Chars called s as an argument
'a' to 'z'                  //create a Range of characters 'a' to 'z'
sliding 3                   //create an Iterator(Seq(a, b, c), Seq(b, c, d), Seq(c, d, e), ... , Seq(x, y, z))
filter{_.toSet subSetOf s}  //keep only the triplets which are a subset of s

2

其实是13个位元组

欢迎打高尔夫球。在线尝试!

S3@╧`εj`M3úV∩

开球

                Implicit input string s.
S               sorted(s).
 3@╧            Push all length-3 combinations of s.
    `εj`M       Join all of those combinations into single strings.
         3úV    Push all slices of the lowercase alphabet of length 1 <= n <= b
            ∩   Push the intersection of the combinations and slices.
                Implicit return.

1

Java 7,230字节

String c(char[]q){java.util.Arrays.sort(q);char a[]=new String(q).replaceAll("(.)\\1","$1").toCharArray(),c=97,i=2;String r="",z="",s;for(;c<'z';z+=c++);while(i<a.length)if(z.contains(s=""+a[i-2]+a[i-1]+a[i++]))r+=s+" ";return r;}

这很可能是打高尔夫球的,但是挑战比我最初在Java中想象的要困难得多。

非高尔夫球和测试用例:

在这里尝试。

class M{
  static String c(char[] q){
    java.util.Arrays.sort(q);
    char a[] = new String(q).replaceAll("(.)\\1", "$1").toCharArray(),
         c = 97,
         i = 2;
    String r = "",
           z = "",
           s;
    for(; c < 'z'; z += c++);
    while(i < a.length){
      if(z.contains(s = "" + a[i-2] + a[i-1] + a[i++])){
        r += s+" ";
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("education".toCharArray()));
    System.out.println(c("foghorn".toCharArray()));
    System.out.println(c("cabaret".toCharArray()));
    System.out.println(c("hijacking".toCharArray()));
    System.out.println(c("pneumonia".toCharArray()));
    System.out.println(c("klaxon".toCharArray()));
    System.out.println(c("perform".toCharArray()));
    System.out.println(c("learning".toCharArray()));
    System.out.println(c("dblacghmeifjk".toCharArray()));
  }
}

输出:

cde 
fgh 
abc 
ghi hij ijk 
mno nop 



abc bcd cde def efg fgh ghi hij ijk jkl klm 

只需问为什么使用Java?它不是最适合的语言...?当然需要+ 1…
WallyWest '16

1
@WallyWest好,我是日常生活中的Java开发人员。而且我知道我永远不会在Java的详细程度上赢得任何挑战,但是Java imho中的代码高尔夫仍然很有趣。:)
Kevin Cruijssen

1
猜猜我要在不久的将来提出一些创造性的代码挑战,以便您参与:)尽管如此,还是要做好!
WallyWest'9

1

PowerShell v2 +,93个字节

param($n)97..120|%{-join[char[]]($_,++$_,++$_)}|?{(-join([char[]]$n|sort|select -u))-match$_}

感觉比要求的要长得多,但是我似乎无法再打高尔夫了。

接受输入$n。从循环97120,构建连续的三个字母的字符串-也就是说,直到|?,我们将有abcbcdcde,等管道上。然后,通过Where-Object|?)填充该内容,以仅拉出该子句为true的那些项。这里,子句是1)的输入字符串$n,铸造作为char-array,sortED和select -unique'd,然后-join编回字符串,2)-match针对三个字母串编辑(即,正则表达式匹配)。如果匹配,则单词中包含三个字母的字符串,因此它会过滤掉|?。结果留在管道上,输出是隐式的。

例子

(请注意,这里输出是用空格分隔的,因为我们通过串联将输出字符串化。)

PS C:\Tools\Scripts\golfing> 'education','foghorn','cabaret','hijacking','pneumonia','klaxon','perform','learning'|%{"$_ -> "+(.\close-knit-words.ps1 $_)}
education -> cde
foghorn -> fgh
cabaret -> abc
hijacking -> ghi hij ijk
pneumonia -> mno nop
klaxon -> 
perform -> 
learning -> 

很好的解释。如果可以的话,我给你两票。
WallyWest'9

1

视网膜,106 56字节

D`.
O`.
^
abc¶
{`^(.*)¶.*\1.*
$0¶$1
}T`_l`l;`^.*
2`.*¶?

重复数据删除,排序。添加abc。查找是否找到了子字符串,如果找到,则追加。翻译到下一个子字符串。重复。然后删除前两行。

在线尝试


天真的解决方案:

D`.
O`.
!&`abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz

重复数据删除,排序,然后输出3个连续字母的重叠匹配项。

在线尝试


天真的解决方案看起来很简单……尽管我更喜欢您的高尔夫解决方案……做得好!
WallyWest'9

1

JavaScript(Firefox 48),93个字节

x=>[for(c of a=[...new Set(x,i=0)].sort())if(parseInt(d=c+a[++i]+a[i+1],36)%1333==38&!d[3])d]

这使其适用于96字节的ES6版本

x=>[...new Set(x)].sort().map((c,i,a)=>c+a[i+1]+a[i+2]).filter(x=>!x[3]&parseInt(x,36)%1333==38)

怎么运行的

该函数的第一个主要块是:

[...new Set(x)].sort()

new Set(string)创建一个Set对象,该对象包含字符串中每个唯一字符之一。例如,new Set("foghorn")将返回Set ["f", "o", "g", "h", "r", "n"]。我们可以使用将其转换为数组[... ],然后使用内置函数对其进行排序.sort()。这变成"foghorn"["f", "g", "h", "n", "o", "r"]

下一步是这样的:

.map((c,i,a)=>c+a[i+1]+a[i+2])

这将每个c在haracter array与后两个项目连接起来的字符。例如,["f", "g", "h", "n", "o", "r"] => ["fgh", "ghn", "hno", "nor", "orundefined", "rundefinedundefined"]。(undefined当您尝试访问数组中不存在的成员时,将弹出s。

最后一步是过滤:

.filter(x=>!c[3]&parseInt(x,36)%1333==38)

首先,!c[3]&排除所有包含的字符串undefined。这是必需的,因为错误会导致以下算法计数为例如gmundefined连续的三元组。

当将所有三个连续的char字符串解释为以36为底的数字时,它们都是38模1333的模数。我通过以下计算得出了这一点:

  • 012(基数36)= 38
  • 123(基数36)= 1371
  • 1371-38 = 1333
  • 1371 mod 1333≡38 mod 1333≡38

因此,如果以36为基数的字符串在base-36中为38 mod 1333,则三个字符在字母表中是连续的。

测试片段


对于诸如gem和的单词,此操作将失败mage
尼尔,

因此,当您说从十六进制(基数36)转换回时,所有连续的字母三元组在对1333进行mod运算时均为38 ...这简直太棒了!
WallyWest'9

@Neil固定为六个字节。
ETHproductions's

我挪用!c[3]了把我的ES6答案降低到以前的ES6答案的长度的把戏,所以现在我什至超过了Firefox 30+答案。对于那个很抱歉。
尼尔

@Neil我不在乎:)
ETHproductions

1

拍子237字节

(define(f s)(let((lr(λ(l i)(list-ref l i)))(l(sort(map char->integer(string->list s))<)))(for((i(-(length l)2)))
(when(=(-(lr l(+ i 2))(lr l(+ i 1)))1(-(lr l(+ i 1))(lr l i)))(for((j 3))(display(string(integer->char(lr l(+ i j))))))))))

测试:

(f "education")

输出:

cde

详细版本:

(define(f2 s)
  (let ((lr (λ(l i)(list-ref l i)))
        (l (sort (map char->integer (string->list s)) <)))
  (for ((i (-(length l)2)))
    (when (=  (- (lr l (+ i 2)) (lr l (+ i 1)))
              1
              (- (lr l (+ i 1)) (lr l i)))
      (for((j 3))
        (display (string(integer->char (lr l (+ i j))))))))))

1

Ruby,50个字节

each_cons(3)从字母表中获取长度为3的所有连续子列表?a..?z,然后使用e&s.chars==esetwise相交仅选择目标字符串中所有字符的子列表。返回列表列表。

->s{(?a..?z).each_cons(3).select{|e|e&s.chars==e}}

在线尝试!


1

[R],110个字节

 f=function(b){a=combn(sort(utf8ToInt(b)),3);apply(unique(t(a[,which(apply(diff(a),2,prod)==1)])),1,intToUtf8)}

我确定它仍然可以打高尔夫球


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.