Anarchy Golf 946. left pad

,

http://golf.shinh.org/p.rb?left+pad

数の処理の場合、sedはbrainfuckより難しいように思った。

ruby 41byte

http://golf.shinh.org/reveal.rb?left+pad/kimiyuki_1458833086

#!ruby -pl
~/ \d+ /;$_=$'.rjust$&.to_i,$`

暫定最短解。 / \d+ // \d+./かの違いを除き全てこれ。 1,2系ともに同一。 mitchsさん、xsotさん、olfさん、Histocratさんと私が提出。

~/ \d+ /$_を3分割し、そのままな処理をしてくれる関数に投げる。

perl 38byte

http://golf.shinh.org/reveal.rb?left+pad/kimiyuki_1458880680

print$`x(/ \d+ /+$&-length$').$' for<>

暫定最短解。 加算の順序等の違いを除き同一。 tailsさん、teebeeさん、llhuiiさんと私が提出。

rjustのようなものはないので、普通に実装する。/ \d+ /1であることを使う。

c

そろそろcもやろうかなと思った。 ozyさんの蟹本は買って積んであるし読まねば。

私 91byte

http://golf.shinh.org/reveal.rb?left+pad/kimiyuki_1459320135

main(c,d,s){for(;~scanf("%c%d%*c",&c,&d);puts(s))for(d-=strlen(gets(s));0<d--;)putchar(c);}
main(c,d,s) {
    for (; ~ scanf("%c%d%*c",&c,&d); puts(s))
        for (d -= strlen(gets(s)); 0 < d -- ;)
            putchar(c);
}

schar **envであるが、これを文字列用の領域として使用している。それ以外は特に変なことはしていない。

xsotさん 84byte

http://golf.shinh.org/reveal.rb?left+pad/xsot_1459225714

d;main(c,s){while(~scanf("%c%d%c",&c,&d))puts(memset(s-d,c,d-=strnlen(gets(s),d)));}
d;
main(c,s) {
    while (~ scanf("%c%d%c",&c,&d))
        puts( memset(s-d, c, d -= strnlen( gets(s), d)));
}

strlenでなくstrnlenを使いd >= 0を保証し、その上でsの手前をmemsetし、そのまま出てきた第1引数をputs

anagolでは引数が右から評価されるらしい。 一般には、実引数の評価順序は規定されていない。

llhuiiさん 86byte

http://golf.shinh.org/reveal.rb?left+pad/llhuii_1459127983

c;main(i,s){for(;i-->strlen(s)?putchar(c):gets(s-scanf("%c%d",&c,&i)/2,c&&puts(s)););}

lphaさんの86byteもだいたい同じ。

c;
main(i,s) {
    for (; i -- > strlen(s)
            ? putchar(c)
            : gets( s - scanf("%c%d",&c,&i) / 2, c && puts(s)); )
        ;
}

staticな変数cの初期値は$0$であるので、初回の実行ではc && puts(s)によりputs(s)は短絡により実行されない。 成功時のscanfの返り値が$2$となることを使い、gets(s-1)とすることにより、余分な空白を除去している。

sed

\x01 \x02 \04 \x09(tab文字)は見やすさのため^A ^B ^D ^Iに置換してある。 文字列先頭の^と紛らわしいが、これは一切使われていない。

私 216byte

http://golf.shinh.org/reveal.rb?left+pad/kimiyuki_1459271849

縮まず。プロらに$2$倍差つけられた。

h
s/. //
s/ .*//
s/./;&9876543210/g
s/;\(.\)[^;]*\1/;/g
t
:
s/\([^;]*\);/\1\1\1\1\1\1\1\1\1\1/
t
G
s/\n\(.\).*/\^A\1/
t1
:1 s/\(.\)^A\(.\)/^A\2\2/
t1
s/..//
G
s/\n. [^ ]* /^A^B/
t2
:2
s/.\(^A.*\)^B\(.\)/\1\2^B/
t2
s/^A\|^B//g

tailsさん 113byte

http://golf.shinh.org/reveal.rb?left+pad/tails_1459181117

だいたい何やってるかは分かるけど、同じようなの思い付けと言われるとまだ厳しい。

:
s/^A/^B9876543210&9^B/
s/\(.\)^B.*\1\(^A*.\).*^B/\2/
t
s/.*^I./&^I/
/^I$/s/./&&/
s/ \w\+/&^A^I/
/ 0*^A/!b
s/. \w*^A^I* \|^I//g
s/ \w\+/&^A^I/

まず実行されるのがこの行。幅の数字列の後ろに^A^Iを付与。

/ 0*^A/  ! b

その次の行では、数字列がなんらかの$0$を表すものでなければ、先頭へ。

s/^A/^B9876543210^A9^B/
s/\(.\)^B.*\1\(^A*.\).*^B/\2/

数字列の末尾に^Aがあるのでこれを置換し、 最下位の数字に対応する位置まで削り、削った次の文字だけ残す。 つまりdecrement。なので繰り下がりも処理する。それが0であった場合は、そこを^A9にした上でもう一度。

s/.*^I./&^I/

.*は最も末尾の^I.を選択するために存在する。そのようなものの次の文字の後ろに^Iを加える。 Ixxxxxから始めて、IxIxxxx IxIxIxxx IxIxIxIxx IxIxIxIxIxI IxIxIxIxIxIと続き、終わる。 出力幅から文字列長を引いている。

/^I$/  s/./&&/

もし末尾に^Iがあるなら、先頭の一文字を複製。 余った出力幅分、文字を複製している。

s/. \w*^A^I* \|^I//g

まだ数字が残っていればもう一度。 そうでなければこの行で不要な文字を消去し終わる。

%20さん 115byte

http://golf.shinh.org/reveal.rb?left+pad/%2520_1459311591

:
s/^I/^A10^I987654321^B/
s/\(.\)^A.*\1\(^I*.\).*^B/\2/
t
s/ \S\+/&^I/
/^I ^D/s/./&&/
/^I ^D/!s/.^D\|$/^D&/
T
s/. 0*^I //
T
s/^D//g
s/ \S\+/&^I/

最初の実行はこの行。 幅の数字列の後ろに^I

/^I ^D/ ! s/.^D\|$/^D&/

次にこの行の選言の右により、文字列末尾に^D

T
s/. 0*	 //
T

この最後のTを踏んで冒頭へ。

s/^I/^A10^I987654321^B/
s/\(.\)^A.*\1\(^I*.\).*^B/\2/

はdecrement。tailsさんのと同じ。captureした文字まで読んでその次の文字だけ残す。

s/ \S\+/&^I/

再度、幅の数字列の後ろに^I

/^I ^D/s/./&&/
/^I ^D/!s/.^D\|$/^D&/

^Dを手前にずらし、^Iまでずらし終われば先頭を複製。

mitchsさん (+ tailsさん, %20さん) 110byte

http://golf.shinh.org/reveal.rb?left+pad/mitchs+%28tails%2C%2520%29_1459425072

終了後の提出。

:
s/^A/^B9876543210&9^B/
s/\(.\)^B.*\1\(^A*.\).*^B/\2/
t
s/.*^I./&^I/
/^I$/s/./&&/
s/ \w\+/&^A^I/
T
s/. 0*^A^I* //
T
s/^I//g

前半はtailsさんのものそのまま、後半Tからは主に%20さんのものが強くまざっている。

brainfuck

私 179byte

http://golf.shinh.org/reveal.rb?left+pad/kimiyuki_1459327248

,+[->>,>,<[>-->+<<--]>[>[<-<+>>-]<<<[>>++++++++++<<-]>>[<<+>>-],<[>-->+<<-]>]>--
----<+[->>,<[>->+<<-]>]+>+[<[+<<]>>[>>]<-]<--[<+[<<+>>-]<]<<+>[-<-[>>>]<<]<[<.>-
]>>[>>>]>>[.>>]>,+]
,+[-
    @c
    >>,>, space and first digit
    c 0 32 @d
    <[>-->+<<--]>[
        c n 0 @d 16
        >[<-<+>>-]<
        <<[>>++++++++++<<-]>>
        [<<+>>-]
    ,<[>-->+<<-]>]
    c n 0 @0 16
    >------<+[-
        >>,<[>->+<<-]>
    ]
    c n 0 0 0 s 0 s 0 s * 0 s 0 @0 10
    +>+[
        <[+<<]
        >>[>>]<-
    ]
    <--
    c n 0 0 0 s 0 s 0 s * 0 s 0 @10
    [
        <+[<<+>>-]<
    ]
    c n l @0 0 s 0 s 0 s * 0 s 0 10
    <<+>[
        -<-[>>>]<<
    ]
      @0 c 0  l 0 0 s 0 s 0 s * 0 s 0 10
    or   c n @0 0 0 s 0 s 0 s * 0 s 0 10
    <[<.>-]
    >>[>>>]
    >>[.>>]>
,+]

数文字負番地にはみ出す。

$2$文字目の空白は捨ててよい定数$32$なので、これを使い回す。 まず$2$で割って$16$にし、$2$倍して引いて空白$32$判定、さらに$1$倍を引いて、数字$48 \dots 57$を数$0 \dots 9$に。 $6$引いて改行$10$にし、これで改行判定しながら読み、読み終わったら引いた分を足し戻す。 最後は文字列の末尾に置いておいて出力に使う。

mitchsさん 124byte

http://golf.shinh.org/reveal.rb?left+pad/mitchs_1458831504

,+[->,>,<[>-<-]>[<[>++++++++++<-]>[<+>-],>++++++++[<----<-->>-]<]-[[<]<[->]>>[>]
<+>,----------]+[<]<[<.>-]>>[+++++++++.>],+]

簡潔でかつ短くてすごい。

,+[-
    >,>,
    c 32 @d
    <[>-<-]>
    c 0 @d
    [
        c n @d
        <[>++++++++++<-]>
        [<+>-]
        ,
        >++++++++[<----<-->>-]<   A
    ]
    c n @0
    -[
        [<]<[->]>>[>]   B
        <+>
    ,----------]
    c n 0 s s s @0
    +
    [<]<[<.>-]
    >>[+++++++++.>]
,+]

2文字目の空白は3文字目にぶつけて消費し、

        >++++++++[<----<-->>-]<   A

で、$16$引くのと$32$を引くのを同時にやっている。

        [<]<[->]>>[>]   B

では読み込みと同時に出力幅をdecrementしている。