字符串的分解图


39

您是否不喜欢将机器或物体分解成最小零件的那些分解图

在此处输入图片说明

让我们来做一个字符串!

挑战

编写一个程序或函数

  1. 输入仅包含可打印ASCII字符的字符串;
  2. 将字符串分解为非空格等号字符组(字符串的“段”);
  3. 以任何方便的格式输出这些组,并在组之间使用一些分隔符

例如,给定字符串

Ah, abracadabra!

输出将是以下几组:

!
,
一种
aa
bb
C
d
H
rr

输出中的每个组均包含相等的字符,并删除了空格。换行符已用作组之间的分隔符。以下是有关允许格式的更多信息。

规则

输入应该是一个字符串或字符数组。它仅包含可打印的ASCII字符(包括从空格到波浪号的范围)。如果您的语言不支持,则可以采用代表ASCII码的数字形式的输入。

您可以假定输入至少包含一个非空格字符

输出应包括字符(即使输入是由ASCII码装置)。组之间必须有明确的分隔符,与输入中可能出现的任何非空格字符不同。

如果输出是通过函数返回,则它也可以是一个数组或字符串,或一个字符数组的数组,或类似的结构。在这种情况下,结构可提供必要的分隔。

每组字符之间的分隔符是可选的。如果有一个,则应用相同的规则:输入中不能出现非空格字符。此外,它不能与组之间使用的分隔符相同。

除此之外,格式是灵活的。这里有些例子:

  • 组可能是用换行符分隔的字符串,如上所示。

  • 这些组可以用任何非ASCII字符分隔,例如 ¬。上述输入的输出将是字符串:

    !¬,¬A¬aaaaa¬bb¬c¬d¬h¬rr
    
  • 这些组可以用n > 1个空格分隔(即使n是可变的),每个组之间的字符也用一个空格分隔:

    !  ,    A   a a a a a    b b  c       d   h  r r
    
  • 输出也可以是函数返回的数组或字符串列表:

    ['!', 'A', 'aaaaa', 'bb', 'c', 'd', 'h', 'rr']
    
  • 或char数组的数组:

    [['!'], ['A'], ['a', 'a', 'a', 'a', 'a'], ['b', 'b'], ['c'], ['d'], ['h'], ['r', 'r']]
    

根据规则,不允许使用的格式示例:

  • 逗号不能用作分隔符(!,,,A,a,a,a,a,a,b,b,c,d,h,r,r),因为输入内容可能包含逗号。
  • 不允许在组(!,Aaaaaabbcdhrr)之间放置分隔符,或在组之间和组内使用相同的分隔符(! , A a a a a a b b c d h r r)。

这些组可以以任何顺序出现在输出中。例如:字母顺序(如上述示例中所示),字符串中首次出现的顺序,...顺序不必是一致的甚至是确定性的。

请注意,输入内容不能包含换行符,A并且a它们是不同的字符(分组是区分大小写的)。

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

测试用例

在每个测试用例中,第一行是输入,其余行是输出,每组都在不同的行中。

  • 测试用例1:

    啊,阿布拉卡达布拉!
    !
    ,
    一种
    aa
    bb
    C
    d
    H
    rr
    
  • 测试案例2:

    \ o / \ o / \ o /
    ///
    \\\
    oo
    
  • 测试案例3:

    一个人,一个计划,一条运河:巴拿马!
    !
    ,,
    :
    一种
    P
    aaaaaaaaa
    C
    二
    毫米
    nnnn
    p
    
  • 测试案例4:

    她说:“告诉我你是怎么做到的,那个让我尖叫的方法。”
    ”
    ,
    小号
    aa
    抄送
    dd
    ee
    h
    ii
    kk
    毫米
    ñ
    oo
    rr
    ssss
    tttttt
    ü
    w
    ÿ
    

1
如果我们使用“-”之类的非ASCII符号作为分隔符,是否可以将其计为1个字节?
Leaky Nun

5
@LeakyNun不,它会按照与源代码所使用的编码相同的方式进行计数,与往常一样
Luis Mendo

最后一组后面的换行符是否可以接受?
JustinM-恢复莫妮卡

领先的换行输出是否可以接受?
DJMcMayhem

1
@RohanJhunjhunwala干得好!:-)是,有几个换行符作为分隔符是好的
路易斯Mendo

Answers:


11

果冻,5个字节

ḟ⁶ṢŒg

在线尝试!

它确实返回一个数组,只是当它被打印到STDOUT时,分隔符消失了。

这确实是一个可调用的函数为这样的(在果冻,每一行是一个功能)。

ḟ⁶ṢŒg
ḟ⁶      filter out spaces
  Ṣ     sort
   Œg   group

23

Python 3.5 +,77 46 44 41字节

lambda s:[a*s.count(a)for a in{*s}-{' '}]

很简单 通过将字符串转换为集合(使用Python 3.5的扩展的可迭代解包)来遍历字符串中的唯一字符,然后使用列表理解通过使用计数每个字符在字符串中出现的次数,从而构造分解图str.count。我们通过从集合中删除空格来过滤掉它们。

输出的顺序可能因运行而异。集合是无序的,因此不能保证处理它们的项的顺序以及由此得到的答案输出。

这是一个lambda表达式;到,前缀用它lambdaf=

在Ideone上尝试! Ideone使用Python 3.4,这还不够。

用法示例:

>>> f=lambda s:[a*s.count(a)for a in{*s}-{' '}]
>>> f('Ah, abracadabra!')
[',', 'A', 'aaaaa', 'd', '!', 'bb', 'h', 'c', 'rr']

感谢@shooqie,节省了3个字节!


3
恭喜1k!
路易斯·门多

2
在Python> 3.5,你可以做{*s}set(s)
shooqie

11

视网膜,13字节

O`.
!`(\S)\1*

排序非常简单(这是内置的),它可以将占用9个字节的字母分开。在线尝试!

第一行O显示regex的所有匹配项.(这是每个字符),给我们 !,Aaaaaabbcdhrr

Match是程序最后一行的默认阶段,并!使其打印以换行符分隔的正则表达式匹配列表。正则表达式在一行中查找一个或多个非空格字符的实例。


什么!做?
Downgoat


8

Perl 6,28个字节

*.comb(/\S/).Bag.kv.map(*x*)

请注意,像HashSet这样的Bag是无序的,因此不能保证结果的顺序。

说明:

# Whatever lambda 「*」


# grab the characters
*.comb(
  # that aren't white-space characters
  /\S/
)
# ("A","h",",","a","b","r","a","c","a","d","a","b","r","a","!")


# Turn into a Bag ( weighted Set )
.Bag
# {"!"=>1,","=>1,"A"=>1,"a"=>5,"b"=>2,"c"=>1,"d"=>1,"h"=>1,"r"=>2}


# turn into a list of characters and counts
.kv
# ("!",1,",",1,"A",1,"a",5,"b",2,"c",1,"d",1,"h",1,"r",2)


# map over them 2 at a time
.map(
  # string repeat the character by the count
  * x *
)
# ("!",",","A","aaaaa","bb","c","d","h","rr")

7

VIM,50,46个字节

i <esc>:s/./&\r/g
:sor
qq:%s/\v(.)\n\1/\1\1
@qq@qD

说明/ gif稍后会出现。


1
一次,Emacs和vim解决方案看起来很相似。
YSC

7

佩斯,6

.gk-zd

在这里尝试或运行测试套件

非常简单,-zd从输入中删除空格,然后.gk将每个剩余元素按其值分组。不幸的是,我还没有找到一种利用自动填充变量的方法。请注意,输出显示为Python字符串,因此某些字符(读取:反斜杠)被转义。如果您希望它更具可读性,请j在代码开头添加a 。


7

Haskell,38个字节

f s=[filter(==c)s|c<-['!'..],elem c s]

基本上是nimi的解决方案,但是显式地仅检查出现在字符串中的字母。


6

2sable,7个字节

码:

Úð-vyÃ,

说明:

Ú       # Uniquify the string, aabbcc would result into abc
 ð-     # Remove spaces
   vy   # For each character...
     Ã  #   Keep those in the string, e.g. 'aabbcc', 'a' would result into 'aa'
      , #   Pop and print with a newline

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


3
听起来根本不像丹尼斯:-P
路易斯·门多

6

JavaScript(ES6),41个字节

s=>[...s].sort().join``.match(/(\S)\1*/g)

这是否还会导致条目" "也存在于返回的数组中?不知道是否允许
价值墨水

@ValueInk Bah,我一开始就考虑过这一点,但很快就忘记了。立即修复。
尼尔

嗯,join()那些双后卫怎么称呼他?
2016年

1
@TejasKale这是ES6模板字符串。当您将方法作为模板字符串的前缀时,它将模板作为数组传递给该方法,因此,在这种情况下,它最终调用.join([''])join然后将其转换为(空)字符串,并使用它来连接数组元素。并非所有方法都将其参数转换为字符串,但是此技术对那些方法很方便。
尼尔


5

Haskell,40个字节

f x=[v:w|d<-['!'..],v:w<-[filter(==d)x]]

用法示例:f "Ah, abracadabra!"-> ["!",",","A","aaaaa","bb","c","d","h","rr"]

该模式v:w仅匹配具有至少一个元素的列表,因此将忽略所有不在输入中的字符。

同样是40个字节:

import Data.List
group.sort.filter(>' ')

@ThreeFx:group也是来自Data.List。无论如何,我认为这种语法ghci仅仅是并且需要REPL,因此它是一种自己语言。我想坚持使用标准的Haskell。
nimi

4

Ruby,41 +1 = 42字节

+1字节的-n标志。

gsub(/(\S)(?!.*\1)/){puts$1*$_.count($1)}

在stdin上接受输入,例如:

$ echo 'Ah, abracadabra!' | ruby -ne 'gsub(/(\S)(?!.*\1)/){puts$1*$_.count($1)}'
A
h
,
c
d
bb
rr
aaaaa
!

4

C#125 98字节

using System.Linq;s=>s.GroupBy(c=>c).Where(g=>g.Key!=' ').Select(g=>new string(g.Key,g.Count())));

说明

//Using anonymous function to remove the need for a full signature 
//And also allow the implicit return of an IEnumerable
s =>

    //Create the groupings
    s.GroupBy(c => c)

    //Remove spaces
    .Where(g=> g.Key!=' ')

    //Generate a new string using the grouping key (the character) and repeating it the correct number of times
    .Select(g => new string(g.Key, g.Count()));
  • 感谢@TheLethalCoder建议使用匿名函数,该函数还允许我删除ToArray调用并仅隐式返回IEnumerable,该IEnumerable总共节省了27个字节

您可以通过将其编译为Func<string, string[]>ie 来节省18个字节(如果我没有正确计算的话)s=>s.GroupBy....
TheLethalCoder 16'Aug

@TheLethalCoder您确定可以代替函数吗,我一直对此保持警惕,因为它增加了很多额外的样板来执行它,并且带有要求使用Linq的参数似乎...错了。
JustinM-恢复莫妮卡

这是我最近做的一个例子…… codegolf.stackexchange.com/a/91075/38550只要允许使用功能,它将删除所有样板
TheLethalCoder

@TheLethalCoder好,对我来说足够好了。:)这也使我可以删除ToArray调用
JustinM-恢复莫妮卡(Monica),2016年

4

R,198 189 96 95字节

for(i in unique(a<-strsplit(gsub(" ","",readline()),"")[[1]]))cat(rep(i,sum(a==i)),"\n",sep="")

松散

a<-strsplit(gsub(" ","",readline()),"")[[1]] #Takes the input from the console

for(i in unique(a)) #loop over unique characters found in variable a

cat(rep(i,sum(a==i)),"\n",sep="") # print that character n times, where n was the number of times it appeared

\涉及到该解决方案时,目前还不能完全起作用。
现在它是 !

谢谢了很多你@JDL打高尔夫球了102个字节!


@JDL:请在评论中建议编辑。您所做的更改确实很有趣,但是像这样更改其他人的代码有点不礼貌。
弗雷德里克

1
对此表示歉意,但当时我没有50个声誉,也无法发表评论。将来会做!
JDL

@JDL:足够公平!
弗雷德里克

尝试在函数内分配变量:for(i in unique(a=strsplit(gsub(" ","",readline()),"")[[1]]))cat(rep(i,sum(a==i)),"\n",sep="")-保存2个字节。
安德烈KOSTYRKA

@AndreïKostyrka:它不会以这种形式保存字节,因为您必须将整个a = strsplit(...)部分放在方括号之间:基本上有-2 + 2的区别。但是,使用 <-将节省1个字节!
弗雷德里克·

4

Swift,105 91字节

感谢@NobodyNada的14个字节:)

是的,我是Swift的新手...

func f(a:[Character]){for c in Set(a){for d in a{if c==d && c != " "{print(c)}}
print("")}}

组中的字符由单个换行符分隔。组由两个换行符分隔。


您可以通过使用input [Character]而不是a 来节省13个字节String,因为规则说“输入应该是字符串或字符数组”。同样,print("")可以用just代替print()
NobodyNada-恢复莫妮卡

@NobodyNada print由于某些原因无法进行辩论,但该[Character]建议是可靠的。谢谢!
jrich

3

八度,61字节

@(x)mat2cell(y=strtrim(sort(x)),1,diff(find([1 diff(+y) 1])))

这是一个匿名函数,将字符串作为输入并输出单元格的字符串数组。

试试Ideone吧

这个怎么运作

  • sort对输入字符串进行排序。特别是空格将在开头。
  • strtrim 删除前导空格。
  • diff(+y) 计算字符之间的连续差异(以检测组边界)...
  • ...因此diff(find([1 diff(+y) 1])给出了组大小的向量。
  • mat2cell 然后将排序后的字符串分成具有这些大小的块。

3

Mathematica,36个字节

内置函数GatherCharacters做大部分的工作在这里。

Gather@Select[Characters@#,#!=" "&]&

3

> <>,49个字节

i:0(?v
84}0~/&{!*
v!?: <}/?=&:&:<
>&1+&}aol1-?!;^

输出非常浪费,但是鉴于规则的宽松性,我认为仍然允许

说明:

i:0(?v           Collects text from input
84}0~/&{!*       adds 32 (first ascii starting at space) to register and 0 to stack
v!?: <}/?=&:&:<  checks all characters to the current register, if equal:
       o         prints the character and continues looping
>&1+&}aol1-?!;^  when all characters are checked, adds 1 to register, prints a newline,
                 checks the stack length to halt the program if 0, and starts looping again

非常紧密地适合一些东西,甚至使用跳转来绕过某些功能,这样我就可以垂直运行指针。

基本上,这会将每个ASCII字符放在自己的换行符上,如果不存在该字符,则该行将为空白

在线尝试

编辑:我错了,代码中有错误,如果输入中有空格,它将导致它永远无法完成


3

Pyth,5个字节

.gksc

在这里尝试!

将输入作为Python字符串(即根据需要用引号,转义引号和斜杠包装)。

说明:

    c    Split (implied) input on whitespace
   s     Sum together
.gk      Group by value

如果保证输入中至少有一个空格,则有一个4字节的解决方案:

t.gk

在这里尝试!

说明:

 .gk (Q)  groups the characters in the string by their value
           this sorts them by their value, which guarantees that spaces are first
t         Remove the first element (the spaces)

3

PowerShell v2 +,44字节

[char[]]$args[0]-ne32|group|%{-join$_.Group}

将输入$args[0]作为命令行参数文字字符串。将其char强制转换为-array,并使用-not equal运算符提取空格(ASCII 32)。之所以可行,是因为强制转换具有较高的优先级,并且当数组用作标量为右手的左手运算符时,它的作用类似于过滤器。

我们将该字符数组传递给Group-Object,它完全按照其说明进行操作。请注意,由于我们传递的是字符而不是字符串,因此可以区分大小写地正确分组。

现在,我们有了一个自定义的对象,它具有组名,计数等。如果仅打印,就会有许多无关的输出。所以,我们需要这些管道进入一个循环|%{...},并在每次迭代-join.Group汇集成一个字符串。这些结果字符串留在管道上,并且在程序完成时隐式输出。

PS C:\Tools\Scripts\golfing> .\exploded-view-of-substrings.ps1 'Programming Puzzles and Code Golf'
PP
rr
ooo
gg
aa
mm
i
nn
u
zz
ll
ee
s
dd
C
G
f


2

处理中,109字节

void s(char[] x){x=sort(x);char l=0;for(char c:x){if(c!=l)println();if(c!=' '&&c!='\n'&&c!='\t')print(c);l=c;}}

它是蛮力方法,对数组进行排序,然后遍历整个数组。如果与最后打印的字符不匹配,请先打印换行符。如果是空白,请跳过打印步骤。


2

Javascript(使用外部库-可枚举)(78 67字节)

 n=>_.From(n).Where(y=>y!=' ').GroupBy(x=>x).WriteLine(y=>y.Write())

链接到lib:https : //github.com/mvegh1/Enumerable

代码说明:这就是Enumerable要做的!将字符串加载到库中,该库将其转换为char数组。过滤出空白项。按字符分组。根据指定的谓词,将每个组写入一行。该谓词表示将当前组的所有元素连接到字符串中,而没有定界符。

在此处输入图片说明



2

Perl6,48 47 45

slurp.comb.Bag.kv.map:{$^a.trim&&say $a x$^b}

感谢manatwork的改进。


1
没有太大的改进,但$a.trim似乎可以根据情况进行。
manatwork'1

逻辑运算符似乎仍然不需要在其周围留有空间,因此 $^a.trim&&say $a x$^b可以工作。(很抱歉逐字节添加提示,但这是我第一次尝试使用Perl6。)
manatwork

小错字,您不小心将开口拆掉了{
manatwork'1

1

Ruby,46个字节

在线尝试!

->s{(s.chars-[' ']).uniq.map{|c|c*s.count(c)}}

我的原始完整程序版本,添加n标志后48个字节:

p gsub(/\s/){}.chars.uniq.map{|c|c*$_.count(c)}

您可以替换.count(c).count c
Cyoce

@Cyoce不,因为*操作员在附近,所以解析器将抱怨。
价值墨水

括号内的s.chars- [''] | []可以避免uniq
GB

@GB可以,但是如果我们将其链接到,map则它需要额外的paren,并且((s.chars-[' '])|[]).map具有与相同的字符数(s.chars-[' ']).uniq.map。@Jordan已在另一种答案中介绍了另一种更短的方法来检查唯一字符(通过正则表达式)(通过正则表达式)
Value Ink

方括号内起作用,您不需要多余的括号,因为“-”的优先级更高。
GB

1

巨蟒,107

可以用lambda来缩短,但后来

x=sorted(input())
i=0
while i<len(x):x[i:]=['  '*(x[i]!=x[i-1])]+x[i:];i-=~(x[i]!=x[i-1])
print("".join(x))

1

CJam,10个字节

{S-$e`::*}

一个未命名的块,其期望字符串位于堆栈的顶部,并将其替换为字符串列表。

在线尝试!

说明

S-  Remove spaces.
$   Sort.
e`  Run-length encode, gives pairs [R C], where R is the run-length and
    C is the character.
::* Repeat the C in each pair R times.

1

普通Lisp 123

(lambda(s &aux(w(string-trim" "(sort s'char<))))(princ(elt w 0))(reduce(lambda(x y)(unless(char= x y)(terpri))(princ y))w))

取消高尔夫:

(lambda (s &aux (w (string-trim " " (sort s 'char<))))
  (princ (elt w 0))
  (reduce
    (lambda (x y) 
      (unless (char= x y) (terpri))
      (princ y))
  w))

不是最友好的高尔夫语言。可以将其修改为返回列表列表,而不是打印字符串。


1

Emacs,36次击键

C-SPACE C-EM-xsort-rTABRETURN.RETURN.RETURNC-AC-M-S-%\(\(.\)\2*\)RETURN\1C-QC-JRETURN!

结果

A man, a plan, a canal: Panama! ->

!
,,
:
A
P
aaaaaaaaa
c
ll
mm
nnnn
p

说明

  1. C-SPACE C-E
  2. M-x sort-rTAB RETURN .RETURN .RETURN
  3. C-A
  4. C-M-S-% \(\(.\)\2*\)RETURN\1 C-Q C-JRETURN !

  1. 选择输入线;
  2. 调用sort-regexp-fields带参数的..;
    • 参数1:正则表达式指定要排序的记录
    • 参数2:正则表达式在记录中指定键
  3. 在行开始处返回;
  4. 在所有匹配项上应用正则表达式替换\(\(.\)\2*\)-> \1\n
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.