文字列の分解図


39

機械やオブジェクトを最小の断片に分解した分解図が好きではありませんか?

ここに画像の説明を入力してください

それを文字列にしましょう!

チャレンジ

以下のプログラムまたは関数を作成します

  1. 印刷可能なASCII文字のみを含む文字列を入力します。
  2. 文字列を非スペースの等しい文字(文字列の「断片」)のグループに分割します。
  3. これらのグループを便利な形式で出力します。グループ間にはセパレータがあります

たとえば、与えられた文字列

Ah, abracadabra!

出力は次のグループになります。

!
、
A
ああああ
bb
c
d
h
rr

出力の各グループには、スペースが削除された等しい文字が含まれています。グループ間の区切り文字として改行が使用されています。許可されている形式については、以下をご覧ください。

ルール

入力は、文字列または文字の配列であるべきです。印刷可能なASCII文字(スペースからチルダまでの範囲)のみが含まれます。ご使用の言語でサポートされていない場合は、ASCIIコードを表す数字の形式で入力を取得できます。

入力には少なくとも1つの非スペース文字が含まれると想定できます。

出力は、からなるべき文字(入力がASCIIコードによるものである場合でも)。グループ間には、入力に現れるスペース以外の文字とは異なる明確な区切り文字が必要です。

出力が関数の戻り値を介している場合、配列または文字列、または文字の配列の配列、または同様の構造体である可能性があります。その場合、構造は必要な分離を提供します。

各グループの文字の区切り文字オプションです。ある場合、同じルールが適用されます。入力に現れる可能性のあるスペース以外の文字は使用できません。また、グループ間で使用されるのと同じセパレーターであってはなりません。

それ以外は、フォーマットは柔軟です。ここではいくつかの例を示します。

  • 上記のように、グループは改行で区切られた文字列です。

  • グループは、などの非ASCII文字で区切ることができます ¬。上記の入力の出力は文字列になります。

    !¬,¬A¬aaaaa¬bb¬c¬d¬h¬rr
    
  • グループはn > 1スペースで区切ることができます(nが可変であっても)。各グループ間の文字は1つのスペースで区切られます。

    !  ,    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

グループは、出力に任意の順序で表示されます。例:アルファベット順(上記の例のように)、文字列に最初に現れる順序、...順序は一貫していたり​​、決定的であったりする必要はありません。

入力は、改行文字が含まれ、そしてできないことに注意してくださいAa異なる文字(グループがある場合、sentitive)。

バイト単位の最短コードが優先されます。

テストケース

各テストケースでは、最初の行が入力され、残りの行は出力であり、各グループは異なる行にあります。

  • テストケース1:

    ああ、アブラカダブラ!
    !
    、
    A
    ああああ
    bb
    c
    d
    h
    rr
    
  • テストケース2:

    \ o / \ o / \ o /
    ///
    \\\
    おー
    
  • テストケース3:

    男、計画、運河:パナマ!
    !
    、、
    :
    A
    P
    aaaaaaaaa
    c
    ll
    mm
    nnnn
    p
    
  • テストケース4:

    「あなたがそのトリックをどのように行うかを見せてください。
    「」
    、
    S
    ああああ
    cc
    dd
    eeeeeee
    うん
    ii
    kk
    んー
    n
    ああ
    rr
    ssss
    tttttt
    あなたは
    ww
    y
    

1
「¬」のような非ASCII記号をセパレータとして使用する場合、1バイトとしてカウントできますか?
リーキー修道女

5
@LeakyNunいいえ、通常どおり、ソースコードに使用されているエンコーディングに応じて対応するものとしてカウントされます
ルイスメンドー

最後のグループの後に続く改行は受け入れられますか?
JustinM -復活モニカ

出力の主要な改行は受け入れられますか?
DJMcMayhem

1
@rohanjhunjhunwalaよくやった!:-)はい、セパレータとしてのいくつかの改行は問題あり
ません

回答:



23

Python 3.5 +、77 46 44 41バイト

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

ものすごく単純。文字列をセットに変換して(Python 3.5の拡張反復可能アンパックを使用して)文字列内の一意の文字を調べ、リスト内包表記を使用して、文字列で各文字が出現する回数をカウントして展開図を作成しますstr.count。セットからスペースを削除することにより、スペースを除外します。

出力の順序は実行ごとに異なる場合があります。セットは順序付けられていないため、アイテムが処理される順序、したがってこの回答の出力は保証されません。

これはラムダ式です。使用するには、接頭辞をlambda付けf=ます。

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は、正規表現.(すべての文字)のすべての一致をrtし、を与え !,Aaaaaabbcdhrrます。

一致は、プログラムの最終行のデフォルトのステージで!あり、正規表現の一致の改行区切りリストを出力します。正規表現は、行内のスペース以外の文字の1つ以上のインスタンスを探します。


何が!行う?
ダウンゴート


8

Perl 6、28バイト

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

なお、バッグなどのハッシュまたはセットが順不同であるので、結果の順序は保証されません。

説明:

# 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

Pyth、6

.gk-zd

ここで試してみるか、テストスイートを実行してください

非常に簡単で-zd、入力からスペースを削除し、.gk残りの各要素をその値でグループ化します。残念ながら、自動入力変数を使用する方法は見つかりませんでした。出力はPython文字列として表示されるため、特定の文字(バックスラッシュ)がエスケープされることに注意してください。読みやすくする場合jは、コードの先頭にa を追加します。



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()ええと、これらの二重バッククティックでどのように呼ばれていますか?
Tejasケール

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は、少なくとも1つの要素を持つリストのみに一致するため、入力にないすべての文字は無視されます。

また、40バイト:

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

@ThreeFx:でもgroup、からData.Listです。とにかく、この構文はghciREPLのみであり、REPLが必要だと思うので、独自の言語です。私は標準のHaskellに固執したいです。
nimi

4

Ruby、41 + 1 = 42バイト

-nフラグ用に+1バイト。

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呼び出しを削除し、27バイトをまとめて保存するIEnumerableを暗黙的に返すこともできました。

(私が正しくカウントされている場合)、あなたはそれをコンパイルすることにより、18のバイトを保存することができFunc<string, string[]>、すなわちs=>s.GroupBy....
TheLethalCoder

@TheLethalCoderは、関数の代わりに受け入れられることを確信しています。それを実行できるようにするために余分なボイラープレートがかなり追加され、それを使用するLinqを要求するための引数が...よく間違っています。
JustinM -復活モニカ

私がやる最近の例は... codegolf.stackexchange.com/a/91075/38550関数が許可されている限り、すべてのボイラープレートが削除されます
-TheLethalCoder

@TheLethalCoder OKそれで十分です。:)また、ToArray呼び出しを削除することもできました
JustinM-モニカの復元16年

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
そのことをおologiesびしますが、私は当時50の評判がなく、コメントをすることができませんでした。しかし、将来的にはやります!
JDL

@JDL:結構です!
フレデリック

関数内で変数を割り当ててみてください。— for(i in unique(a=strsplit(gsub(" ","",readline()),"")[[1]]))cat(rep(i,sum(a==i)),"\n",sep="")2バイトを節約します。
アンドレイKostyrka 16

@AndreïKostyrka:a = strsplit(...)部分全体を括弧で囲む必要があるため、この形式ではバイトを保存しません。基本的に-2 + 2の違いがあります。ただし、使用 <-すると1バイト節約されます!
フレデリック

4

Swift、105 91バイト

14バイトの@NobodyNadaに感謝します:)

ええ、私はスウィフトにかなり新しいです...

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

グループ内の文字は、単一の改行で区切られます。グループは2つの改行で区切られます。


ルールでは「入力は文字列または文字の配列である必要がある」と言われているため、入力をaの[Character]代わりにa として使用すると、13バイトを節約できますString。また、print("")だけで置き換えることができますprint()
NobodyNada -復活モニカ

print引数なしの@NobodyNada は何らかの理由で機能しませんでしたが、[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

> <>、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

入力に少なくとも1つのスペースを保証する場合、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の目的です!文字列をライブラリにロードし、ライブラリが文字配列に変換します。空白のエントリを除外します。文字ごとにグループ化します。指定された述語に従って、各グループを行に書き込みます。この述語は、現在のグループのすべての要素を区切り文字なしで文字列に結合することを示しています。

ここに画像の説明を入力してください



2

Perl6の、48 47 45

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

改善のためのmanatworkに感謝します。


1
大きな改善ではありませんが、$a.trimその状態のためにそれを行うようです。
マナトワーク

論理演算子はまだそれらの周りにスペースを必要としないように見えるので、 $^a.trim&&say $a x$^b動作します。(バイト単位でヒントを追加して申し訳ありませんが、これはPerl6での最初の試行です。)
manatwork

少し間違えましたが、誤って開口部を削除しました{
マナトワーク

1

ルビー、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いいえ。*オペレーターが近くにいるので、パーサーは文句を言います。
バリューインク

s.chars- [」「] | []括弧内はuniqのを避けるだろう
GB

@GBそれはそうなりますが、それを連鎖させるmap場合、余分な括弧が必要((s.chars-[' '])|[]).mapで、文字数と同じです(s.chars-[' ']).uniq.mapです。また、一意の文字を(正規表現を介して)確認するもう1つの短い方法は、別の回答
値インク

できます 内のブラケット、の優先順位ので、あなたは余分な括弧を必要としない「 - 」の高くなっています。
GB

1

Python、107

ラムダで短縮できますが、後で

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

Common 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すべての一致に適用します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.