週刊Challz 081タスクシュノーラ1:楽


TASK #1 › Common Base String
提出されます:モハメッドsアンワール
You are given 2 strings, $A and $B.

Write a script to find out common base strings in $A and $B.

    A substring of a string $S is called base string if repeated concatenation of the substring results in the string.
Example 1:

Input:
    $A = "abcdabcd"
    $B = "abcdabcdabcdabcd"

Output:
    ("abcd", "abcdabcd")

Example 2:

Input:
    $A = "aaa"
    $B = "aa"

Output:
    ("a")
私の通常の出発点は、我々が入力を得る方法です?
二つの文字列が与えられます.それでは、2つの個々の変数を取得する方法は?
sub MAIN ( Str \A, Str \B ) {
   say A, ",", B;
}
shell> raku ch-1.raku a aaa
a,aaa
ところで、変数の値を変更したくない場合
"\varname "構文を使用することができます.
それで、「A」、「B」は現在不変の変数です.
この課題のほとんどの原則は「文字列のサブストリングを得る方法」です問題はない、我々はsubstr method
sub MAIN ( Str \A, Str \B ) {
   B.substr( 0 .. 1 ).say;
}
shell> raku ch-1.raku a aaa
aa
「0 . 1」を見ることができるのはRangeであり、ここでのインデックス番号です.
それで、あなたが『A』会社を持っているとき、ウェイターに「1のためのテーブル」を言わなければなりません.いいえ.どうぞ.
ベースワードは各単語の先頭からサブ文字を含んでいなければならない
我々がさらに進む前に、我々が便利なオペレーター"x" String repetition operatorについて知っていなければならないもう一つのもの
shell> raku # interactive shell for raku 😍
To exit type 'exit' or '^D'
> "o" x 5
ooooo
いくつかの制限を加えたので、指定された文字列のどれよりも長いベース文字列を作ることは意味がありません.
sub MAIN ( Str \A, Str \B ) {
    my ( @answer, $shorter );

    # shorter version of bellow
    # $shorter = A.chars < B.chars ?? A !! B

    if A.chars < B.chars {
        $shorter = A;
    }
    else {
        $shorter = B;
    }

    for 1..$shorter.chars -> $num-char {
        my $mcb = $shorter.substr( ^$num-char ); # mcb: maybe common base string
        #        `-> another way of A.substr( 0..$num-char);

        next unless A.chars %% $num-char and B.chars %% $num-char;

        if ( A eq $mcb x ( A.chars div $num-char )
            and
            B eq $mcb x ( B.chars div $num-char ) ) {
            @answer.push( $mcb );
        }
    }
    @answer.say;
}
わかりました.これは“A”ソリューションです.
rakuは本当に優れたドキュメントを持っています.
何か興味があるなら、書類をチェックしてください.
%演算子: https://docs.raku.org/routine/$PERCENT_SIGN$PERCENT_SIGN
そして、我々がより多くの(本当に)便利な砂糖を加えるならば
比較ブロック、変更されます.
...
        if ( A eq $mcb x ( A.chars div $num-char )
            and
            B eq $mcb x ( B.chars div $num-char ) ) {
            @answer.push( $mcb );
...
なる
...
        if (A,B).map(
            -> $str {
                $mcb x ( $str.chars div $num-char ) } ).all == True {
            @answer.push( $mcb );
...
良い.ルックストレンディ関数型プログラミング
「すべて」は、私のために魔法を見ます.我々は試みるべきだ.
如何ですか.
shell> raku
To exit type 'exit' or '^D'
> any( 1 == 0, "abc" eq "def", ("I love Raku".substr(0,5) eq ("I love Perl".substr(0,5)))) == True
any(False, False, True)
> (any( 1 == 0, "abc" eq "def", ("I love Raku".substr(0,5) eq ("I love Perl".substr(0,5)))) == True).so
True
しかし、もう一つのもの...
楽にはgcdがある
最大公約数
A、Bストリングは、公約数の倍数の長さを持たなければなりません.
shell> raku
To exit type 'exit' or '^D'
> "abc".chars gcd "abcabc".chars
3
それで、私は新しい友人「GCD」を使用することによって、もう一つの解決をすることができました
sub MAIN ( Str \A, Str \B ) {
    my @words = A, B;
    my @answer;

    my $gcd  = A.chars gcd B.chars;

    for 1..$gcd -> $maybe-cd {
        if $gcd %% $maybe-cd {
            note "$maybe-cd is common divisor";

            my $mcb = A.substr(^$maybe-cd);
            if @words.map(
                { $mcb x ($_.chars div $maybe-cd)
                  eq
                  $_ } ).all == True {
                note "found a base substring: $mcb";
                @answer.push( $mcb );
            }
        }
    }
    note "therefore:";
    @answer.join(", ").put;
}
shell> raku ch-1.blog.raku "abcdabcd" "abcdabcdabcdabcd"
1 is common divisor
2 is common divisor
4 is common divisor
found a base substring: abcd
8 is common divisor
found a base substring: abcdabcd
therefore:
abcd, abcdabcd

そしてGCDとindicesに基づくもう一つの解決策
閉じるこの動画はお気に入りから削除されています.
sub MAIN(*@a) {
    say (1..([gcd] @a>>.chars)).
    map(->\k{my \w = @a[0].substr(^k);
          next if any @a.map({.indices(w).elems!= .chars/k});
          w } )
}
より多くのコンセプトのために必要な説明は、コードを通過するが、私はまだraku ..閉じるこの動画はお気に入りから削除されています.
> ("what I told" ~~ True, "today" ne "tommorrow", "I don't know something but it's working so I used.".so eq True).all.so
False
それで、別のエピソードを待ってください.
ありがとう〜!