インターリーブ文字列


30

インスピレーション。*私たちが以前にこの課題に直面したことはないと信じられません

仕事

1つ以上の印刷可能なASCII文字列が与えられた場合、各文字列から1文字ずつ、文字がなくなるまで周期的にインターリーブします。文字列が他の文字より前に文字を使い果たした場合、それ以降はその文字をスキップします。

SIMPLE 与える SIMPLE

POLLSそしてEPEES与えるPEOPLELESS

LYESそしてAPRONS与えるLAYPERSONS

ABCDEそしてa cそして123 567与えるAa1B 2Cc3D E567

"\n$?*そして(空の文字列)と,(.)" (末尾のスペース)は",\(n.$)?"* (末尾のスペース)を与える


*より短いAPLソリューションがあります。


これは基本的に単なる転置操作であるため、非常によく似たいくつかの課題がありましたが、まったく同じものはありませんでした。
マーティンエンダー

7
CS HWでこの質問がありましたが、これは宿題の質問としてこれを終了できるということですか?; P
ダウンゴート16

@EriktheOutgolferかっこいい!今日は何かを学びました。
アダム

回答:


23

ゼリー、1バイト

Z

オンラインでお試しください!

「トランスポーズ」ビルトインは、文字列のリストに対してこれを正確に行います。


短い文字列にスペースを埋め込む必要がある場合、コードはどのように見えますか?
アダム16

2
それになりますz⁶z「左に転置し、右にパディングする」。スペースです。
リン

1
@AdámJellyはリストで非常にうまく機能します。ビルトインはどこで終わり、言語構造/設計はどこから始まりますか?
steenbergh

1
@Lynn In Jelly?AtomsおよびQuicksリストにあるものはすべて組み込みです。
アダム

2
@Adám ;"(要素ごとの連結)は、組み込みなしでタスクを解決します。
デニス

8

Python 2、101 89 86 69バイト

私はこれをなんとかラムダに入れて、それを再帰的にすることで短くすることを望んでいます。転置が短くなることを望んでいるので、それは理想的ではありません(残念ながら、これはそうではありません)。

f=lambda s:' '*any(s)and''.join(x[:1]for x in s)+f([x[1:]for x in s])

古いソリューション:

w=input();o=''
while any(w):
 for i in range(len(w)):o+=w[i][:1];w[i]=w[i][1:]
print o

lambda s:''.join(''.join([c,''][c<' ']for c in x)for x in map(None,*[list(y)for y in s]))

w=input();o=''
while any(x>=' 'for x in w):
 for i in range(len(w)):o+=w[i][:1];w[i]=w[i][1:]
print o

バカな気分にさせてくれたmathmandanに感謝します;)(古いソリューション)


できませんwhile any(w):か?Pythonでは空の文字列は偽です。
mathmandan 16

私は...考えていたかわからない、あなたが絶対的に正しい@mathmandan
カーデ

問題ありません:)を追加する必要があると思うことを除いて、新しいソリューションは素晴らしいですf=
mathmandan

[]再帰呼び出しをオフにして、を残すことができf(x[1:] for x in s)ます。これにより、ジェネレーター内包表記となり、このコンテキストのリストと同じように機能します。
バイオウィーゼル




6

JavaScript(ES6)、52 46バイト

f=([[c,...s],...a])=>s+a?c+f(s+s?[...a,s]:a):c

入力を文字列の配列として受け取り、単一の文字列として出力します。

テストスニペット

f=([[c,...s],...a])=>s+a?c+f(s+s?[...a,s]:a):c

g=a=>console.log("Input:",JSON.stringify(a),"Output:",JSON.stringify(f(a)))

g(["SIMPLE"])
g(["POLLS","EPEES"])
g(["LYES","APRONS"])
g(["ABCDE","a c","123 567"])
g(["\"\\n$?*",",(.)\" "]) // Backslash and quote are escaped, but in/output are correct


f=([[c,...s],...a])=>c?c+f([...a,s]):a+a&&f(a)
ニール

@Neilそれは素晴らしいアプローチです。私は自分で6バイトゴルフをやった:
ETHproductions

6

Haskell、33バイト

import Data.List
concat.transpose

Ideoneでお試しください。使用法:

Prelude Data.List> concat.transpose$["ABCDE","a c","123 567"]
"Aa1B 2Cc3D E567"

ビルトインを使用しない場合:(38 34バイト)

f[]=[]
f x=[h|h:_<-x]++f[t|_:t<-x]

Ideoneでお試しください。Zgarbのおかげで4バイトオフ!使用法:

Prelude> f["ABCDE","a c","123 567"]
"Aa1B 2Cc3D E567"

1
代替バージョンのすべての括弧を削除できます。それでもインポートに勝るものはありません。
ズガルブ16

実際にベースケースが必要ですか?
XNOR

もちろん、基本ケースが必要です。
XNOR

@xnorまた、ベースケースを最後に移動してf a=a、バイトを保存するためにそれを置き換えることはできません。なぜなら、両方[]とも異なるタイプを持っているからです...とても近いです。
ライコニ16

5

C、114 84バイト

長さを計算しない場合は-20バイト。

i,b;f(char**s){b=1;while(b){i=-1;b=0;while(s[++i]>0)if(*s[i])putchar(*s[i]++),++b;}}

charポインターの配列を受け入れ、最後の項目がNULLポインターであることを要求します(使用法を参照)。

ゴルフをしないと使用法:

i,b;f(char**s){
 b=1;
 while(b){
  i=-1;
  b=0;
  while(s[++i]>0)
   if(*s[i])
    putchar(*s[i]++),++b;
 }
}


int main(){
 char*a[]={ 
//  "POLLS","EPEES"
//  "LYES","APRONS"
 "ABCDE","a c","123 567"
 ,0};
 f(a);
 puts("");
}

printf / sprintfの使用は許可されていませんか?:Dあなたはかなりのバイトを獲得するでしょう。
ウォルフラット16

@Walfrat直接印刷せずに文字列を割り当てる必要があるので、これで何を節約できますか。
カールナップ16

編集の前に++ bを追加し、長さの計算を削除したため、yesはもう機能しません。
ウォルフラット16

はい@Walfrat、しかし、私は持っていたmallocし、return前に、これは単なる印刷するよりも長かった
カールNAPFを

5

PHP、68 67バイト

for(;$f=!$k=$f;$i++)for(;y|$v=$argv[++$k];$f&=""==$c)echo$c=$v[$i];

コマンドライン引数をループします。で実行し-rます。

内部ループの後、$fある1すべての文字列が、終了したとき0(ビット単位の他に&キャストを""==$cintに)。
外側のループの次の反復:コピー$f$k(1バイトから節約$k=0とトグル)$f
すべての文字列が完了したら、$ffalseとループが壊れますが。


空の入力文字列では機能しません。最後のテストケースを見てみましょう
aross

@aross:修正されました。ありがとう。
タイタス

4

網膜、13バイト

バイトカウントはISO 8859-1エンコードを前提としています。

O$#`.
$.%`
¶

オンラインでお試しください!

説明

O$#`.
$.%`

これは、Retinaの標準的な転置技術に基づいています。O改行以外のすべての文字(.$#を、同じ行($.%`)の前にある文字数()でソートします(つまり、水平位置)。

2番目の段階では、入力から改行を削除するだけです。


4

Java(登録商標)、19 + 155 = 174 160

String f(java.util.Queue<String> q){String s,r="";while(!q.isEmpty()){s=q.poll();r+=s.isEmpty()?"":s.charAt(0);if(s.length()>1)q.add(s.substring(1));}return r;}

ゴルフをしていない:

  String f(java.util.Queue<String> q) {
    String s, r = "";
    while (!q.isEmpty()) {
      s = q.poll();
      r += s.isEmpty() ? "" : s.charAt(0);
      if (s.length() > 1) {
        q.add(s.substring(1));
      }
    }
    return r;
  }

出力:

シンプル

人が少ない

レイパーソンズ

Aa1B 2Cc3D E567

「、(n。$)?」*

最初の変更:文字列宣言をマージして、いくつかのバイトを節約しました。削除importされ、main()これも必要なメソッド(ここには示されていません)によって使用されましたLinkedListQueue直接参照する方が少ないバイトです。


文字列rの初期化文字列sは、さらにいくつかの保存することができます
Syamesh K

:数バイトのゴルフを、私はそれをほぼ一年前になっていますけど、あなたのことができString f(java.util.Queue<String>q){String s,r="";for(;!q.isEmpty();r+=s.isEmpty()?"":s.charAt(0))if((s=q.poll()).length()>1)q.add(s.substring(1));return r;}
ケビンCruijssen

3

PHP、77バイト

ゴルフ

function($a){for($d=1;$d!=$s;$i++){$d=$s;foreach($a as$v)$s.=$v[$i];}echo$s;}

文字列の配列を受け取る匿名関数。

これはもっとゴルフできると確信していますが、早いです。各反復で、指定された各文字列からi番目の文字を取得し、最終文字列に1つずつ追加します。PHPは、存在しない文字列にアクセスすると警告を発するだけなので、問題ありません。すべての文字列を1回ループした後、変更が行われなかった場合にのみ停止します。

I feel like the usage of $d can be golfed more, but it's early. :P


How exactly do you put an array of strings in a single argument?
Titus

@Titus. Y'know, I never really thought about it. I just kinda assumed you could.
Xanderhall

3

Actually, 7 6 bytes

Golfing suggestions welcome! Try it online!

Edit: -1 byte thanks to Teal pelican.

a Z♂ΣΣ

Ungolfing

          Implicit input each string.
a         Invert the stack so that the strings are in the correct order.
<space>   Get the number of items on the stack, len(stack).
Z         Zip all len(stack) strings into one, transposing them.
♂Σ        sum() every transposed list of chars into strings.
Σ         sum() again to join the strings together.

Can you not remove the # to make it 6 bytes?
Teal pelican

@Tealpelican Welp, now I'm going to have to dig through all of my old Actually answers and see if I can't change Z♂#Σ to Z♂Σ in all of them. Thanks for the tip :D
Sherlock9

First time looking into the language, it looks so much fun! Glad I could help :))
Teal pelican

3

JavaScript (ES6), 46 bytes

f=([[c,...s],...a])=>c?c+f([...a,s]):a+a&&f(a)
<textarea oninput=o.textContent=f(this.value.split`\n`)></textarea><div id=o>



2

J, 13 bytes

({~/:)&;#\&.>

Try it online!

Based on the inspiration for this question.

Another way to do it takes 27 bytes but operates using transpose. Most of the bytes are to handle the automatically added zeroes from padding.

[:u:0<:@-.~[:,@|:(1+3&u:)&>

Explanation

({~/:)&;#\&.>  Input: list of boxed strings S
          &.>  For each boxed string x in S
        #\       Get the length of each prefix from shortest to longest
                 This forms the range [1, 2, ..., len(x)]
                 Rebox it
(    )         Operate on S and the prefix lengths
      &;         Raze both
   /:            Grade up the raze of the prefix lengths
 {~              Index into the raze of S using the grades
               Return

J's prohibiting mixed arrays really hurts you here. Try it in APL.
Adám

2

Bash + GNU utilities, 55

 eval paste `sed "s/.*/<(fold -1<<<'&')/g"`|tr -d \\n\\t

I/O via STDIN (line-separated) and STDOUT.

The sed formats each line to a bash process substitution. These are then evaled into paste to do the actual interleaving. tr then removes unnecessary newlines and tabs.

Ideone.


2

PHP, 63 bytes

Note: uses IBM-850 encoding

for(;$s^=1;$i++)for(;n|$w=$argv[++$$i];$s&=$x<~■)echo$x=$w[$i];

Run like this:

php -r 'for(;$s^=1;$i++)for(;n|$w=$argv[++$$i];$s&=$x<~■)echo$x=$w[$i];' "\"\n\$?*" "" ",(.)\" " 2>/dev/null;echo
> ",\(n.$)?"* 

Explanation

for(                       # Iterate over string index.
  ;
  $s ^= 1;                 # Continue until $s (stop iterating) is 1.
                           # Flip $s so each iteration starts with $s
                           # being 1.
  $i++                     # Increment string index.
)
  for(
    ;
    "n" | $w=$argv[++$$i]; # Iterate over all input strings. OR with "n"
                           # to allow for empty strings.
    $s &= $x<~■            # If last character printed was greater than
                           # \x0 (all printable chars), set $s to 0,
                           # causing the loop to continue.
  )
    echo $x = $w[$i];      # Print char $i of current string.

IBM-850?! Is that a natural encoding for PHP?
Adám

@Adám what do you mean by "natural"? PHP treats bytes in the range 128-255 as text, which is therefore interpreted as a constant. If the constant is undefined, it will be interpreted as a string. It's so I can do ~■ (negated binary 254) instead of "\x1" (binary 1).
aross

1
I see. It isn't that you actually need that codepage, you just need a 254 byte.
Adám

@Adám yes, the codepage just makes it a printable char which is a little less annoying.
aross

Great use of $$!
Titus

2

Python 3, 75 Bytes

I know the other Python one is shorter, but this is the first time I've used map ever in my life so I'm pretty proud of it

lambda n:''.join(i[k]for k in range(max(map(len,n)))for i in n if len(i)>k)

1

C, 75 71 bytes

Only limitation is the output length. Currently it's 99, but can be easily stretched to 999 (+1 byte).

i;main(a,b)char**b;{a--;for(;i<99;i++)*b[i%a+1]&&putchar(*b[i%a+1]++);}

Ungolfed:

i;
main( a, b )
char **b;
{
    a--;
    for( ; i < 99; i++ )
        *b[i % a + 1] && putchar( *b[i % a + 1]++ );
}

1

Oracle SQL, 195 bytes

    select listagg(b,'') within group(order by l,o) from(select substr(a,level,1) b,level l,o from i start with length(a)>0 connect by prior a=a and level<=length(a) and prior sys_guid() is not null)

Takes its input from a table named i with columns a (containing the string) and o (order of the string):

    create table i (a varchar2(4000), a integer)

Explanation:
We're exploiting CONNECT BY to break up the strings into each of the characters making them up. PRIOR SYS_GUID() being NOT NULL ensures we don't end up stuck in a loop.
We then concatenate the single characters with LISTAGG but we shuffle them around with an ORDER BY clause, ordering them first by their position in the original string and only then by the string they came from.

Not as short as the other answers but SQL isn't really meant as a string manipulation language :)


1

Python 2, 128 96

I was hoping not to have to use itertools

a=lambda a:"".join([i for i in reduce(lambda: b,c:b+c, map(None,*map(lambda m:list(m),a)) if i])

Ungolfed

 a=lambda a:                              #Start a lambda taking in a
    "".join(                              #Join the result together with empty string
        [i for i in reduce(               #For every item, apply the function and 'keep'
           lambda: b,c:b+c,               #Add lists from...
                map(None,*map(            #None = Identity function, over a map of...
                    lambda m:list(m), a)  #list made for mthe strings m
                   ) if i                 #truthy values only (otherwise the outer map will padd with None.
       ])

Would appreciate feedback/advice on improving this.
Pureferret


1

R, 73 bytes

for(i in 1:max(nchar(s<-scan(,""))))for(j in seq(s))cat(substr(s[j],i,i))

Try it online!

Explanation: very simple (but verbose), just loop through printing ith character of the jth string. Fortunately, substr returns an empty string if given an out-of-range input.


0

Python, 112 bytes

i=len(x)if len(x)>len(y) else len(y) h=0 a="" while h<i: if h<len(x) a+=x[h] if h<len(y): a += y[h] h+=1 print a

6
Your formatting is really messed up.. where do you even get x and y from?
Kade

0

Perl 5, 53 bytes

$i=0,map{push@{$a[$i++]},$_}/./g for<>;print@$_ for@a

Try it online!

Method

Creates a two dimensional array where the number of rows is equal to the length of the longest string and the maximum number of columns is equal to the number of strings. Then output each row of the array without spacing.


0

TXR Lisp, 20 bytes

(opip weave cat-str)

Run:

1> (opip weave cat-str)
#<intrinsic fun: 0 param + variadic>
2> [*1 "LYES" "APRONS"]
"LAYPERSONS"
3> [*1 "ABCDE" "a c" "" "123 567"]
"Aa1B 2Cc3D E567"
4> [*1 "\"\\n$?*" "" ",(.) "]
"\",\\(n.$)? *"

The weave function is lazy, so it returns a list, which is why we have to force the result to a string. Being lazy, it can weave infinite sequences. For instance, we can weave the even and odd natural numbers, which are themselves infinite lazy lists:

5> (take 20 (weave (range 2 : 2) (range 1 : 2)))
(2 1 4 3 6 5 8 7 10 9 12 11 14 13 16 15 18 17 20 19)

0

K (oK), 35 29 bytes

Solution:

{`c$r@&~^r:,/+(`i$x)[;!#,/x]}

Try it online!

Example:

> {`c$r@&~^r:,/+(`i$x)[;!#,/x]}("ABCDE";"a c";"123 567")
"Aa1B 2Cc3D E567"
> {`c$r@&~^r:,/+(`i$x)[;!#,/x]}("\n$?*";"";",(.)\" ")
"\n,$(?.*)\" "
> {`c$r@&~^r:,/+(`i$x)[;!#,/x]}("POLLS";"EPEES")
"PEOPLELESS"

Explanation:

Use 2nd-level indexing to pull out indices from 0 to max (length of flattened list) across all input lists. Any indexing beyond the bound of the sub-list will return a null. Flip (rotates 90), flatten, and then pull out the non-null results.

Notes:

  • I cast to integer (i$) so that we get useful nulls, as space () is considered null for a char list which means you cant tell nulls from valid spaces.
  • Also I couldnt get the TIO to work with input (worked fine in the oK repl) so the TIO link includes the "ABCDE"... example.

0

Jq 1.5, 49 bytes

map(explode)|transpose|map(map(values)[])|implode

Explanation

                      # example input:          ["LYES","APRONS"]
  map(explode)        # make list of ordinals   [[76,89,69,83],[65,80,82,79,78,83]]
| transpose           # zip lists               [[76,65],[89,80],[69,82],[83,79],[null,78],[null,83]]
| map(map(values)[])  # rm nulls and flatten    [76,65,89,80,69,82,83,79,78,83]
| implode             # convert back to string  "LAYPERSONS"

Sample Run

$ paste input <(jq -Mrc 'map(explode)|transpose|map(map(values)[])|implode' input)
["SIMPLE"]                  SIMPLE
["POLLS","EPEES"]           PEOPLELESS
["LYES","APRONS"]           LAYPERSONS
["ABCDE", "a c", "123 567"] Aa1B 2Cc3D E567
["\"\\n$?*", "", ",(.)\" "] ",\(n.$)?"* 

$ echo -n 'map(explode)|transpose|map(map(values)[])|implode' | wc -c
  49    

Try it online

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