要素単位の文字列乗算


28

この課題に触発され(タイトルに@cairdcoinheringaahingに感謝します!)、あなたの仕事は2つの印刷可能なASCII文字列を取得し、次のルールで要素ごとに乗算することです。

どのように機能しますか?

2つの文字列(たとえばsplitisbn)が与えられた場合、最初に長い文字列を切り捨てて長さが等しくなるようにし、次にASCIIコードを決定します

split -> spli -> [115, 112, 108, 105]
isbn  -> isbn -> [105, 115,  98, 110]

次のステップでは、各コードを[0..94]減算することにより、それらを範囲にマップし32ます。

[115, 112, 108, 105] -> [83, 80, 76, 73]
[105, 115,  98, 110] -> [73, 83, 66, 78]

次に、要素ごとにモジュロを乗算します95(印刷可能な範囲に留まるため)。

[83, 80, 76, 73] ⊗ [73, 83, 66, 78] -> [74, 85, 76, 89]

追加32して範囲に戻ります[32..126]

[74, 85, 76, 89] -> [106, 117, 108, 121]

最後のステップは、それらをASCII文字にマップし直すことです。

[106, 117, 108, 121] -> "july"

ルール

  • 説明した手順を2つの文字列に実装し、結果の文字列を出力または返すプログラム/関数を作成します
  • 入力形式は柔軟です。2つの文字列、文字列のタプル、文字列のリストなどを使用できます。
  • 入力は1つまたは2つの空の文字列で構成されます
  • 入力は、印刷可能な範囲の文字になります([32..126]
  • 出力はコンソールに出力されるか、文字列を返します
  • 出力には末尾の空白を含めることができます

テストケース

"isbn", "split"                  -> "july"
"", ""                           -> ""
"", "I don't matter"             -> ""
"             ", "Me neither :(" -> "             "
"but I do!", "!!!!!!!!!"         -> "but I do!"
'quotes', '""""""'               -> 'ck_iKg'
"wood", "hungry"                 -> "yarn"
"tray", "gzip"                   -> "jazz"
"industry", "bond"               -> "drop"
"public", "toll"                 -> "fall"
"roll", "dublin"                 -> "ball"
"GX!", "GX!"                     -> "!!!"
"4 lll 4", "4 lll 4"             -> "4 lll 4"
"M>>M", "M>>M"                   -> ">MM>"

:引用符は読みやすくするためのもので、6番目のテストケースではの'代わりに使用しました"


出力に末尾のスペースを含めることはできますか?
エリックアウトゴルファー

@EriktheOutgolferはい。申し訳ありませんが、投稿後に追加しました。
ბიმო

文字列の配列の配列を取得できますか?abc, def -> [['a', 'b', 'c'], ['d', 'e', 'f']]
完全に人間の

@totallyhumanそうは言いません。しかし、あなたの言語で文字列が文字の配列であり、文字が文字列と同じ型を持っている場合、それは妥当だと思います。
ბიმო

入力を文字列のリストとして受け取ることはできますか?
ザカリー

回答:


9

MATL、12バイト

c32-p95\32+c

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

説明

c      % Implicitly input cell array of 2 strings. Convert to 2-row char matrix.
       % This pads the shorter string with spaces
32-    % Subtract 32, element-wise. Each char is interpreted as its ASCII code.
       % Note that padding spaces will give 0.
p      % Product of each column. Since (padding) spaces have been mapped to 0, the
       % product effectively eliminates those colums. So the effect is the same as
       % if string length had been limited by the shorter one
95\    % Modulo 95, element-wise
32+    % Add 32, element-wise
c      % Convert to char. Implicitly display

1
文字列の長さの違いを管理する賢い方法。
-Sanchises

6

ゼリー15 12バイト

z⁶O_32P€‘ịØṖ

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

-3 ジョナサンアランに感謝します。


末尾の空白の不正な不正使用。;)
デニス

@Dennisそれはルールにあります、なぜそれを乱用しませんか?
エリックアウトゴルファー

私はあなたが、印刷可能な文字のniladic原子を使って、3バイトを保存することができると信じていØṖて、z⁶O_32P€‘ịØṖ-あなたは最高のダブルチェック算術作品しかしそれを思います。
ジョナサンアラン

@JonathanAllanもちろん。
エリックアウトゴルファー


5

パイソン275の 70バイト

shonisieの提案に対するDennisの提案のおかげで-3バイト。Zacharýの提案のおかげで-2バイト。

lambda*l:''.join(chr((ord(i)-32)*(ord(j)-32)%95+32)for i,j in zip(*l))

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


2
私の答えで提案されたのと同じトリック:lambda*t:''.join(chr(((ord(i)-32)*(ord(j)-32))%95+32)for i,j in zip(*t))
デニス

2
:私は多くのことを示唆していることと同じ1 ((ord(i)-32)*(ord(j)-32))%95+32=> (ord(i)-32)*(ord(j)-32)%95+32...
ザカリー

o_oデニスを破った。+1
ザカリー

1
ええ、実際にはそうではなく、を使用する代わりにリストの内包表記に変更しましたmap。少し遅れました。
完全に人間

5

Haskell60 57バイト

zipWith(\a b->toEnum$f a*f b`mod`95+32)
f=(-32+).fromEnum

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

最初の行は、2つの引数を取る匿名関数です。

これは、アルゴリズムの単純な実装です。zipWith両方の文字列を受け取り、特定の関数を文字のペアに適用します。切り捨てを処理し、空の文字列に対しても機能します。fromEnumtoEnumに代替しているordchr長い輸入を必要としない文字とそのASCII値を切り替えることができます。

編集:ブルースフォルテのおかげで-3バイト。


これらの括弧を3引き出して保存することでバイトを節約できますこちらを-32ご覧ください
ბიმო

5

C ++、331 291 282 270 268バイト、バージョン2 = 178 176 150 148バイト

元のバージョン :

#include<string>
#include<algorithm>
#define L length()
#define S std::string
S m(S a,S b){S c;int m=a.L<b.L?a.L:b.L;auto l=[m](S&s){s=s.substr(0,m);std::for_each(s.begin(),s.end(),[](char&c){c-=32;});};l(a);l(b);for(int i=0;i<m;++i){c+=a[i]*b[i]%95+32;}return c;}

Bruce Forteのおかげで-40バイト
Zacharýのおかげで-39バイト

他の人の答えに触発されたバージョン2

#include<string>
#define L length()
using S=std::string;S m(S a,S b){S c;for(int i=0;i<(a.L<b.L?a.L:b.L);++i)c+=(a[i]-32)*(b[i]-32)%95+32;return c;}

最初のバージョンがラムダを使用している場合、それは前に学んだばかりのC ++ 11 std :: async関数をテストしたかったためです。

より読みやすいバージョン:

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

#define L length()
#define S string

//Function code for the original version
S m(S a,S b) {
    S c;
    int m = a.L < b.L ? a.L : b.L;

    auto l=[m](S&s){
        s = s.substr(0, m);
        for_each(s.begin(),s.end(),[](char&c){
            c -= 32;
        });
    };
    l(a);
    l(b);
    for(int i=0;i<m;++i) {
        c += a[i] * b[i] % 95 + 32;
    }
    return c;
}

//Code for the version 2
S m2(S a,S b) {
    S c;
    for(int i = 0; i < (a.L < b.L ? a.L : b.L); ++i) {
        c += (a[i] - 32) * (b[i] - 32) % 95 + 32;
    }
    return c;
}

int main() {
    string a, b, c;
    getline(cin, a);
    getline(cin, b);
    c = m(a, b);
    cout << c;
}

1
PPCGへようこそ!
マーティンエンダー

サイトへようこそ!お返事ありがとうございます。私はC ++でのゴルフの経験はありませんが、ここにいくつかのヒントがあります。ここで時間をお楽しみください!
ბიმო

また、このように関数を送信するだけでいいと確信しています。
ბიმო

ここでスペースを削除できません:#include <string>=> #include<string>and #include <algorithm>=> #include<algorithm>
ザカリー

さらに、同等のマクロを作成し、stringそれに応じて使用できる必要があります。
ザカリー

3

Dyalog APL、36 34 33 25 24バイト

{⎕UCS 32+95|×⌿32-⎕UCS↑⍵}

オンラインで試してください(TryAPL)!

オンラインで試してください(TIO)!

入力は文字列のリストであり、末尾に空白があります。

仕組みは次のとおりです。

{⎕UCS 32+95|×⌿32-⎕UCS↑⍵}
                     ↑⍵ - the input as a 2d array
                 ⎕UCS   - codepoints
              32-       - subtract 32
            ×⌿          - element wise product reduction ([a,b]=>a×b)
         95|            - Modulo 95
      32+               - Add 32
 ⎕UCS                   - Unicode characters

私はのインターフェースを取得していないtryapl.orgので、ここでは「それを試してみたいという人のためTIOね。
ბიმო

そこに、両方を入れました。
ザカリー



2

C#(.NET Core)100 96 95バイト

(l,n)=>{for(int i=0;i<l.Length&i<n.Length;)Console.Write((char)((l[i]-32)*(n[i++]-32)%95+32));}

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

@Zacharýのおかげで-4バイト

増分を移動して-1バイト

ラムダを使用し、文字が基本的に整数であるという事実を悪用します。


使用できます(l[i]-32)*(n[i]-32)%95+32か?
ザカリー

はい、できます。ありがとう!
-jkelm

1
完全に修飾する必要があり、Consoleカリー化を使用してバイトを保存できます。Action<string, Action<string>>likeにコンパイルしてlike l=>n=>を呼び出す("word")("string")
-TheLethalCoder

2

Mathematica、114バイト

(a=Min@StringLength[x={##}];FromCharacterCode[Mod[Times@@(#-32&/@ToCharacterCode/@(StringTake[#,a]&/@x)),95]+32])&


入力

["public"、 "toll"]


オンラインで試す方法はありますか?
ბიმო

もちろん、sandbox.open.wolframcloud.com / app / objectsにアクセスしてコードを貼り付け、最後に入力を貼り付け、shift + enterを押す
J42161217

「8文字」とは何ですか?
J42161217

混乱させて申し訳ありません!「ありがとう」というメッセージ このように投稿するには短すぎたので、さらに8文字必要でした。
ბიმო

3
ok ....................................-
J42161217

2

積み上げ、52バイト

[,:$#'"!MIN$take"![CS#.toarr]"!32-prod 95%32+#:''#`]

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

スタックから2つの引数を取る関数。

説明

[,:$#'"!MIN$take"![CS#.toarr]"!32-prod 95%32+#:''#`]

上の2つの項目が'split'andであると仮定して、最初の部分を見てみましょう'isbn'

,:$#'"!MIN$take"!      stack:                      ('split' 'isbn')
,                      pair top two:               (('split' 'isbn'))
 :                     duplicate:                  (('split' 'isbn') ('split' 'isbn'))
  $#'                  length function literal:    (('split' 'isbn') ('split' 'isbn') $#')
    "!                 execute on each:            (('split' 'isbn') (5 4))
      MIN              obtain the minimum:         (('split' 'isbn') 4)
         $take         "take" function literal:    (('split' 'isbn') 4 $take)
                       (e.g. `'asdf' 2 take` is `'as'`)
              "!       vectorized binary each:     (('spli' 'isbn'))

この部分はトリミングを実行します。

次に:

[CS#.toarr]"!     stack: (('spli' 'isbn'))
[         ]"!     perform the inside on each string
                  string `'spli'`:
 CS               convert to a character string:    $'spli'
   #.             vectorized "ord":                 (115 112 108 105)
     toarr        convert to array:                 (115 112 108 105)
                  (needed for empty string, since `$'' #.` == `$''` not `()`

次に、最後の部分:

32-prod 95%32+#:''#`  stack: (((115 112 108 105) (105 115  98 110)))
32-                   subtract 32 from each character code:   (((83 80 76 73) (73 83 66 78)))
   prod               reduce multiplication over the array:   ((6059 6640 5016 5694))
        95%           modulus 95:                             ((74 85 76 89))
           32+        add 32:                                 ((106 117 108 121))
              #:      convert to characters:                  (('j' 'u' 'l' 'y'))
                ''#`  join:                                   ('july')

2

R、88バイト

function(r,s,u=utf8ToInt)intToUtf8((((u(r)-32)*(u(s)-32))%%95+32)[0:min(nchar(c(r,s)))])

匿名関数; 入力を2つの文字列として受け取ります。3番目の引数は、これが1行関数であることを確認し、いくつかのバイトを節約することです。

以下のTIOリンクは、最初の入力で名前が付けられたエントリを持つ配列を返します。

すべてのテストケースをお試しください!




2

05AB1E16 15バイト

.BÇ32-`*₃%32+çJ

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

エミニャがプッシュを指す場合は-1 95


                 # ['hi', 'you']
.B               # [['hi ', 'you']]
  Ç              # [[[104, 105, 32], [121, 111, 117]]]
   32-           # [[[72, 73, 0], [89, 79, 85]]]
      `          # [[72, 73, 0], [89, 79, 85]]
       *         # [[6408, 5767, 0]]
        ₃%       # [[43, 67, 0]]
          32+    # [[75, 99, 32]]
             ç   # [['K', 'c', ' ']]
              J  # ['Kc ']

.BÇ32-`*95%žQsèJ

別です。


バイトを保存します。空の文字列入力については残念です。それ以外の場合øは、さらにいくつかの節約になります。
エミグナ

2

Java 8、127 115 97 95バイト

a->b->{for(int i=0;i<a.length&i<b.length;System.out.printf("%c",(a[i]-32)*(b[i++]-32)%95+32));}

説明:

ここで試してみてください。

a->b->{                       // Method with 2 char-array parameters and no return-type
  for(int i=0;                //  Index-integer, starting at 0
      i<a.length&i<b.length;  //  Loop over both arrays up to the smallest of the two
    System.out.printf("%c",   //   Print, as character:
      (a[i]-32)               //    Current char of `a` minus 32
      *(b[i++]-32)            //    multiplied with current char of `b` minus 32
      %95                     //    Take modulo-95 of that multiplied result
      +32));}                 //    And add 32 again

1

C#、166バイト

using System.Linq;s=>t=>{int e=s.Length,n=t.Length,l=e>n?n:e;return string.Concat(s.Substring(0,l).Select((c,i)=>(char)((((c-32)*(t.Substring(0,l)[i]-32))%95)+32)));}

たくさんのゴルフができると確信していますが、今は時間がありません。

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

完全/フォーマット済みバージョン:

using System;
using System.Linq;

class P
{
    static void Main()
    {
        Func<string, Func<string, string>> f = s => t =>
        {
            int e = s.Length, n = t.Length, l = e > n ? n : e;

            return string.Concat(s.Substring(0, l).Select((c, i) => (char)((((c - 32) * (t.Substring(0, l)[i] - 32)) % 95) + 32)));
        };

        Console.WriteLine(string.Concat(f("split")("isbn")));

        Console.ReadLine();
    }
}

私が考える(((c-32)*(t.Substring(0,l)[i]-32))%95)+32)ことができます((c-32)*(t.Substring(0,l)[i]-32)%95+32)(そこに括弧を台無しにしているかもしれない...それはLispのように見ている!)
ザカリー




1

、30バイト

F⌊⟦LθLη⟧℅⁺³²﹪×⁻³²℅§θι⁻³²℅§ηι⁹⁵

オンラインでお試しください!リンクは、コードの詳細バージョンです。(32 - ord(q)) * (32 - ord(h))連続した数値リテラルを回避するため、実際に計算を書いたが、代わりに書いただけだったと思う(ord(q) - ord(" ")) * (ord(h) - ord(" "))


1

Perl 5、95バイト

@a=<>=~/(.)/g;@b=<>=~/(.)/g;$#a=$#b if@a>@b;print chr 32+(-32+ord$_)*(-32+ord$b[$i++])%95 for@a

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

説明:

@a=<>=~/(.)/g;@b=<>=~/(.)/g;  # Split the strings into 2 arrays
$#a=$#b if@a>@b;              # Truncate the first if longer than the second
print chr 32+(-32+ord$_)*(-32+ord$b[$i++])%95 for@a  # Multiply each character

1
結果を小さい文字列の長さに正しく切り捨てていないと思います(こちらを参照)。
ダダ

あなたが正しい。多くのバイトのコストで修正
Xcali

1

ピップ、19バイト

(PA$* *(PA@?Zg)%95)

文字列をコマンドライン引数として受け取ります。 オンラインでお試しください!

説明

(PA$* *(PA@?Zg)%95)
                     g is list of args; PA is string of all printable ASCII characters
            Zg       Zip items of g together: result is list of pairs of characters
        PA@?         Find index of each character in PA
       (      )      (Parentheses to get correct operator precedence)
   $* *              Map (fold on *) to the list: multiplies each pair of numbers
               %95   Take list items mod 95
(PA               )  Use those numbers to index into PA again
                     Print the resulting list of chars, concatenated together (implicit)

1

ファクター、45

[ [ [ 32 - ] bi@ * 95 mod 32 + ] "" 2map-as ]

それは引用(ラムダ)です。 call、スタックに2つの文字列があり、新しい文字列をスタックに残します。

一言で:

: s* ( s1 s2 -- ps ) [ [ 32 - ] bi@ * 95 mod 32 + ] "" 2map-as ;

"M>>M" "M>>M" s*      ! => ">MM>"
dup s*                ! => "M>>M"
dup s*                ! => ">MM>"
...

1

K(オーケー)、26バイト

溶液:

`c$32+95!*/-32+(&/#:'x)$x:

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

例:

`c$32+95!*/-32+(&/#:'x)$x:("split";"isbn")
"july"

説明:

評価は右から左に実行されます。

`c$32+95!*/-32+(&/#:'x)$x: / the solution
                        x: / assign input to variable x
                       $   / pad right to length on left
               (  #:'x)    / count each x (return length of each char list in list)
                &/         / min-over, get the minimum of these counts
           -32+            / subtract 32, this automagically converts chars -> ints
         */                / multiply-over, product of the two lists
      95!                  / modulo 95
   32+                     / add 32 back again
`c$                        / convert to character array

0

PHP、112バイト

for($i=0;$i<min(strlen($a=$argv[1]),strlen($b=$argv[2]));$i++)echo chr((ord($a[$i])-32)*(ord($b[$i])-32)%95+32);

109バイト: for($i=0;$i<strlen($a=$argv[1])&&$i<strlen($b=$argv[2]);)echo chr((ord($a[$i])-32)*(ord($b[$i++])-32)%95+32);交換する場合にも、私は全くわからない&&&かもしれないこともに別のバイトで、それを減らす、PHPで可能で108
ケビンCruijssen

0

JavaScript(ES6)、89バイト

Javascriptと長い関数名の呪い...

カリー化と、無効な位置で呼び出されたときにcharCodeAt戻るファクトを使用しますNaN。出力には末尾のヌルが含まれる場合があります。

a=>b=>a.replace(/./g,(c,i)=>String.fromCharCode((z=x=>x.charCodeAt(i)-32)(a)*z(b)%95+32))

テスト

var f=
a=>b=>a.replace(/./g,(c,i)=>String.fromCharCode((z=x=>x.charCodeAt(i)-32)(a)*z(b)%95+32))

q=x=>'['+x+']'

;[["isbn", "split"],["", ""],["", "I don't matter"],["             ", "Me neither :("],
["but I do!", "!!!!!!!!!"],['quotes', '""""""'],["wood", "hungry"],["tray", "gzip"],
["industry", "bond"],["public", "toll"],["roll", "dublin"],["GX!", "GX!"],
["4 lll 4", "4 lll 4"],["M>>M", "M>>M"]]
.forEach(([a,b])=>console.log(q(a)+' x '+q(b)+' --> '+q(f(a)(b))))

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