配列を数学の問題に変える


35

非負の整数の空でないリストが与えられた場合、それを算術問題として書き直すことを検討してください。

  • プラス記号(+)は、左から右へ(つまり、リストの先頭から末尾へ)増加する数値のペアの間に挿入されます。
  • マイナス記号(-)は、左から右に向かって減少する数値のペアの間に挿入されます。
  • 乗算記号(*)は、等しい数のペアの間に挿入されます。

別の言い方をすると、サブリストa,ba+bif a<ba-bif a>b、およびa*bifになりa==bます。

たとえば、リスト

[12, 0, 7, 7, 29, 10, 2, 2, 1]

表現になるだろう

12 - 0 + 7*7 + 29 - 10 - 2*2 - 1

これはに評価され 75ます。

そのようなリストを取り込んで評価し、結果を出力または返すプログラムまたは関数を作成します。

  • 操作の順序が重要です。乗算は、加算または減算の前に実行する必要があります。
  • 入力リストに1つの数値がある場合、それが評価されるものでなければなりません。例えば、[64]与える必要があります64
  • evalまたはexec、同様の構成要素の使用が許可されています。

追加の例を次に示します。

[list]
expression
value

[0]
0
0

[1]
1
1

[78557] 
78557
78557

[0,0]
0*0
0

[1,1]
1*1
1

[2,2]
2*2
4

[0,1]
0+1
1

[1,0]
1-0
1

[1,2]
1+2
3

[2,1]
2-1
1

[15,4,4]
15-4*4
-1

[9,8,1]
9-8-1
0

[4,2,2,4]
4-2*2+4
4

[10,9,9,12]
10-9*9+12
-59

[1,1,2,2,3,3]
1*1+2*2+3*3
14

[5,5,4,4,3,3]
5*5-4*4-3*3
0

[3,1,4,1,5,9,2,6,5,3,5,9]
3-1+4-1+5+9-2+6-5-3+5+9
29

[7637,388,389,388,387,12,0,0,34,35,35,27,27,2]
7637-388+389-388-387-12-0*0+34+35*35-27*27-2
7379

バイト単位の最短コードが優先されます。Tiebreakerは以前の回答です。


5
「操作の順序が重要」に関して、加算と減算は左結合であり、同じ優先順位を持っていることを明示的に述べるのが良いかもしれません。
マーティンエンダー

回答:


15

Python 2、63バイト

p=s='print-'
for x in input():s+='*+-'[cmp(x,p)]+`x`;p=x
exec s

eval式の文字列を作成して、sにします。算術記号は、前の数字pと現在の数字を比較して選択しxます。記号の後に現在の番号が追加されます。

最初の数字は、Sp3000の巧妙なトリックで処理されます。の初期値はp文字列に設定されますが、これは任意の数値よりも大きいため-、最初の数値の前にaが発生します。しかし、結果を開始すると同時ににs初期化さprint-れますprint--(で初期化して2バイトを節約したxsotに感謝しprintます)。


print文字列に移動してのexec代わりに使用できると思いますeval
xsot

13

Pyth、31 26 19 17 16 15バイト

の式は*オンラインで評価されませんが、理論的には機能します。

Maltysenのおかげで2バイト。

vsm+@"*-+"._-~k

テストスイート(評価付き)。

その他の場合(評価なし)。

歴史

  • 31バイト: M+G@"*-+"->GH<GHv+sgMC,JsMQtJ\x60e
  • 26バイト: M+G@"*-+"->GH<GHv+sgVQtQ\x60e
  • 19バイト: vtssVm@"*-+"->Zd<~Z
  • 17バイト: vtssVm@"*-+"._-~Z
  • 16バイト: vssVm@"*-+"._-~k
  • 15バイト: vsm+@"*-+"._-~k

乗算がオンラインで機能しないのはなぜですか?うまくいかない場合は、回答する前にもう少しテストするのが最善かもしれません。
カルビンの趣味

そのため、セキュリティのもの(評価のみのために働く+-オンライン)
漏れ修道女

@HelkaHombaまだオフラインで試す機会はありませんでしたが、うまくいくはずです。オンラインインタープリターは--safeスイッチを使用evalast.literal_evalます。これはに置き換えられます。
デニス

わかりました。
カルビンの趣味

確認済み、これはオフラインインタープリターで機能します。
デニス

12

ゼリー18 16 15 14 バイト

I0;ð1g×⁹⁸œṗP€S

組み込みのevalを使用しません。オンラインでお試しください!または、すべてのテストケースを確認します

使い方

I0;ð1g×⁹⁸œṗP€S  Main link. Input: A (list)

I               Increments; compute the deltas of all adjacent items of A.
 0;             Prepend a 0.
   ð            Begin a new, dyadic chain.
                Left argument: D (0 plus deltas). Right argument: A
    1g          Compute the GCD of 1 and each item in D.
                This yields 1 for non-negative items, -1 for negative ones.
      ×⁹        Multiply each 1 or -1 with the corresponding item of A.
                This negates every item in A that follows a - sign.
        ⁸œṗ     Partition the result by D. This splits at occurrences of non-zero
                values of D, grouping items with identical absolute value.
           P€   Take the product of each group.
             S  Sum; add the results.


1
よくできました。Pythonをevalアトムとして追加する必要があります
デニス

9
私はあなたをゴルフアウトしました。:P
デニス

あなたの番です!
リーキー修道女

9

MATL、12バイト

Y'^l6MdZSh*s

これは、ランレングスエンコーディングに関する@aditsuの非常に優れたアイデアを使用しています。

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

説明

       % Take input vector implicitly
Y'     % RLE. Produces two vectors: values and lengths
^      % Rise each value to the number of consecutive times it appears. This
       % realizes the product of consecutive equal values
l      % Push 1
6M     % Push vector of values again
d      % Consecutive differences
ZS     % Sign function. Gives 1 or -1 (no 0 in this case)
h      % Concatenate horizontally with previous 1
*      % Multiply. This gives plus or minus depending on increasing character
s      % Sum of vector. This realizes the additions or subtractions
       % Display implicitly

ハハは似たようなことを書いたところです。RLEはこのためにうまく動作します
Suever

@Suever私は見ます:-D
ルイス・メンドー

7

CJam、20

q~e`{~_W-g\:W@#*}%:+

オンラインで試す

説明:

q~       read and evaluate the input (array of numbers)
e`       RLE encode, obtaining [count number] pairs
{…}%     map each pair
  ~_     dump the count and number on the stack, and duplicate the number
  W-     subtract the previous number (W is initially -1 by default)
  g      get the sign of the result
  \      swap with the other copy of the number
  :W     store it in W (for next iteration)
  @#     bring the count to the top, and raise the number to that power
  *      multiply with the sign
:+       add all the results together

7

JavaScript(ES6)、54

p=>eval(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

eval 式のコンマ区切りリストを受け取り、最後の値を返します。

テスト

f=p=>eval(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

t=p=>(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

function Test() {
  var a=I.value.match(/\d+/g).map(x=>+x) // convert input to a numeric array
  
  var x=f(a),y=t(a)
  O.textContent='Value '+x+'\n(no eval '+y+')'
}  

Test()
#I { width:80%}
<input value='12, 0, 7, 7, 29, 10, 2, 2, 1' id=I>
<button onclick='Test()'>Test</button>
<pre id=O></pre>


4
これは、このサイトで見た覚えているコンマ演算子の最悪の悪用です
ニール

5

ジュリア、76 57バイト

!x=[[" ""-*+"[2+sign(diff(x))]...] x]'|>join|>parse|>eval

ジュリアを初めてゴルフしたので、明らかな改善があるかもしれません。 オンラインでお試しください!

デニスは大量のバイトを節約しました。


良くやった。のカスタム関数を定義できることを知りませんでした!
Rɪᴋᴇʀ

@EᴀsᴛᴇʀʟʏIʀᴋcodegolf.stackexchange.com/ a
デニス

4

Pyth- 23 22 20バイト

ケニーの場合と同様に、乗算はオンラインでは機能しません。

vs.i+\+@L"*+-"._M-Vt

evalを実行せずにスイートをテストします。


ケビンは誰ですか?
リーキー修道女

@LeakyNunしばらくして名前を忘れてしまった> _>
Maltysen

@Maltysen母、あなたはケビン・
ノット

申し訳ありませんが、私は食事をしていましたので、解決策をゴルフできませんでした。あなたの番。
リーキー修道女

@LeakyNunがほとんどそこに
Maltysen

3

R、92バイト

ここでできるゴルフはまだまだありそうです。

eval(parse(t=paste(i<-scan(),c(ifelse(d<-diff(i),ifelse(d>0,"+","-"),"*"),""),collapse="")))

ゴルフをしていない:

i = scan()                # Read list from stdin
d = diff(i)               # Calculate difference between each element of list
s = ifelse(d,             # If d!=0
             ifelse(d>0,  # And if d>1
                    "+",  # Return plus
                    "-"), # Else return minus
             "*")         # Else (i.e. d==0) return multiply.
s = c(s,"")               # Pad the list s with an empty string, so it's the same
                          # length as i
p = paste(i,s,collapse="")# Paste the elements of i and s into one long string.
eval(parse(t=p))          # Evaluate the string as a language object.



2

TI-BASIC、146バイト

モバイル以外の場合はうまくフォーマットします。睡眠は私を逃れるので、あなたはこれを取得します。楽しい。

Prompt L₁
"(→Str1
For(A,1,dim(L₁
{0,1→L₂
{0,L₁(A→L₃
LinReg(ax+b) L₁,L₃,Y₁
Equ►String(Y₁,Str2
sub(Str2,1,-1+inString(Str2,"X→Str2
If A>1
Then
L₁(A-1
2+(Ans>L₁(A))-(Ans<L₁(A
Str1+sub("+*-",Ans,1→Str1
End
Str1+Str2→Str2
End
expr(Str1

2

JavascriptをES6、64の 62文字

a=>eval(a.map((x,i)=>x+('*+-'[x<a[++i]|(x>a[i])*2])).join``+1)

3
これは関数とaパラメーターではありませんか?
edc65

これは現状では無効です。
Rɪᴋᴇʀ

@ edc65、はい、そうすべきです。しかし、実際にはカウントされました(61が指定されましたが、実際のコード長は59でした)、新しいコードをひどくコピーしました(編集はa[i+1]...a[i+1]=> a[++i]...a[i]-2文字短くする必要がありますが、誤ってコード全体をドロップしましたa=>)。
-Qwertiy

@EᴀsᴛᴇʀʟʏIʀᴋ、それは間違った貼り付けです。詳細については、上記のコメントを参照し、履歴を編集してください。
-Qwertiy

@Qwertiyいいね、クール。ニースの答えところで...
Rɪᴋᴇʀ

1

Java、384バイト

int s(int[]l){int n=l[0],m;for(int i=0;i<l.length-1;i++)if(l[i]<l[i+1])if(i<l.length-2&&l[i+1]!=l[i+2])n+=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n+=m;}else if(l[i]>l[i+1])if(i<l.length-2&&l[i+1]!=l[i+2])n-=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n-=m;}else{m=l[i];while(i<l.length-1&&l[i]==l[i+1])m*=l[i++];n+=m;}return n;}

Ungolfed オンラインしてみてください

int s(int[] l)
{
    int n=l[0], m;

    for(int i=0; i<l.length-1; i++)
    {
        if(l[i] < l[i+1])
        {
            if (i<l.length-2 && l[i+1]!=l[i+2])
            {
                n += l[i+1];
            }
            else
            {
                m = l[i+1];
                while(i<l.length-2 && l[i+1]==l[i+2]) m *= l[(i++)+1];
                n += m;
            }
        }
        else if(l[i] > l[i+1])
        {
            if (i<l.length-2 && l[i+1]!=l[i+2])
            {
                n -= l[i+1];
            }
            else
            {
                m = l[i+1];
                while(i<l.length-2 && l[i+1]==l[i+2]) m *= l[(i++)+1];
                n -= m;
            }
        }
        else
        {
            m = l[i];
            while(i<l.length-1 && l[i]==l[i+1]) m *= l[i++];
            n += m;
        }
    }

    return n;
}

1
いくつかのクイックゴルフ:int a=l.length&&=> &int i=0と同じ「ライン」に配置しint n=l[0],mます。
漏れの修道女

ではif(i<l.length-2&&l[i+1]!=l[i+2])n+=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n+=m;、これをelseブロック内のコンテンツに置き換えることができます。
リーキー修道女


1

Perl、49バイト

48バイトのコード+ 1 -p

s/\d+ (?=(\d+))/$&.qw(* - +)[$&<=>$1]/ge;$_=eval

使用法

perl -pe 's/\d+ (?=(\d+))/$&.qw(* - +)[$&<=>$1]/ge;$_=eval' <<< '12 0 7 7 29 10 2 2 1'
75

ノート

ここでは、PCREで先読みをキャプチャできることを学びましたが、少し直感的ではありません((?=(\d+))ではなく((?=\d+)))。ただし、長さゼロの一致(先読み)を後者とキャプチャし、代わりに前者との一致をキャプチャするため、読み取り後に意味があります。

8バイトを節約してくれた@ninjaljに感謝します!


@LeakyNunそのために何をカウントすべきか正確にわからない、関連するメタ投稿を見つけることができない、カウントを増やすのはうれしいが-e、無料で実行できるのでp、それ-peを+1 することを追加すると思った?今のところ更新しますが、ソースを見つけることができれば、今後の引用/リンクができれば、それは素晴らしいことです!
ドムヘイスティングス

3
@DomHastings 1は正しい、あなたの言う理由ごとに+ このメタ投稿
Sp3000

ありがとう@ Sp3000!私の人生でその投稿を見つけることができませんでした!@LeakyNun 1のメタポスト SP3000からのコメントどおり
ドムヘイスティングス

連鎖条件演算子を使用する代わりに、宇宙船演算子を使用して、演算子$&.qw(* - +)[$&<=>$1]の置換部分のリストから選択できますs///
ninjalj

@ninjaljもちろん!素晴らしい、ありがとう!-8それで!
ドムヘイスティングス

1

実際には、30バイト

;2@VpXdX`i-su"+*-"E`M' @o♀+εj≡

残念ながら、評価()コマンドはTIOのリテラルのみを評価する、このプログラムはTIOで機能しません。

説明:

;2@VpXdX`i-su"+*-"E`M' @o♀+εj≡
;                               duplicate input
 2@V                            overlapping sublists of length <= 2
    pXdX                        discard first and last element (length-1 sublists)
        `i-su"+*-"E`M           map: for each pair of elements
         i-su                     flatten, subtract, sign, increment (results in a 0 if b < a, 1 if b == a, and 2 if b > a)
             "+*-"E               select the correct operation
                     ' @o       put a space at the beginning of the list to pad it properly
                         ♀+     pairwise addition (since addition is not defined for strings and integers, this just zips the lists and flattens the result into a single flat list)
                           εj   join with empty string
                             ≡  eval

1

R120 44バイト

r=rle(scan());c(1,sign(diff(r$v)))%*%r$v^r$l

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

アルゴリズムはこの答えに似ていますが、答えをコーディングして初めて実現しました。を使用していた私の元の答えよりもはるかに良いeval(parse)

Rのベクトル化された操作を完全に活用します- *操作は最初にrle(x)$values ^ rle(x)$lenghtsこのベクトルを使用してドット積を生成しますsign( diff( rle(x)$values ) )(前に1)。


1

05AB1E(レガシー)17 16 15 バイト

ü.S…*-+sè‚ζJJ.E

@Emignaのおかげで-2バイト。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

ü                  # Pair-wise loop over the (implicit) input-list
                   #  i.e. [12,0,7,7] → [[12,0],[0,7],[7,7]]
 .S                # Calculate the signum of the pair (-1 for a<b; 0 for a==b; 1 for a>b)
                   #  i.e. [[12,0],[0,7],[7,7]] → [1,-1,0]
   …*-+sè          # Index over "*-+" (with wrap-around)
                   #  i.e. [1,-1,0] → ['-','+','*']
         ‚ζ        # Zip the two lists together (appending the operands to the numbers)
                   #  i.e. [12,0,7,7] and ['-','+','*','+']
                   #   → [[12,'-'],[0,'+'],[7,'*'],[7,' ']]
           JJ      # Join them together
                   #  [[12,'-'],[0,'+'],[7,'*'],[7,' ']] → '12-0+7*7 '
             .E    # Evaluate as Python code
                   #  i.e. '12-0+7*7' → 61

1
モジュラーインデックス作成のため、文字列の最後に>移動+して削除できます。
エミグナ

@Emignaどうやってそれを見逃したかわからない。ありがとう!
ケビンCruijssen

1
ƨ‚ζø
-Emigna

@Emignaああ、今ではスマートです!ありがとう。囲い込みが少し奇妙な回避策であることは知っていましたが、それを修正する方法は知りませんでした。‚ζevalではスペースが無視されるため、これは完全な代替手段です。再度、感謝します。:)
ケビンクルーッセン

0

PHP、103バイト

きちんとした挑戦。これは予想よりも長くなりました。PHPではarray_map匿名関数は依然として高価であるため、使用するなどの方法でバイトカウントが改善されることはないと思います。

foreach(fgetcsv(STDIN)as$v)(0<=$p?$o.=$p.('*-+'[($p>$v)+2*($p<$v)]):_)&&$p=$v;echo eval("return$o$v;");

コマンドラインから実行すると、次のようなコンマ区切りリストの入力が求められます。

php array_to_math.php
12, 0, 7, 7, 29, 10, 2, 2, 1

0

PowerShell v2 +、62バイト

-join($args|%{"$o"+'*+-'[($o-lt$_)+2*($o-gt$_)];$o=$_})+$o|iex

スペースで区切られたコマンドライン引数として入力を受け取り、自動配列に変換されます$args。繰り返しごとにヘルパー変数を使用して各要素を反復処理し$o、前のエントリが何であったかを記憶します。暗黙的に変換されたブール値に対して数学を実行することにより、適切な演算子を引き出すためにインデックス付き文字列を使用します(たとえば、前のエントリが小さい場合、[]評価は1+2*0そう選択されることを'*+-'[1]意味し+ます)。

連結された文字列はパイプラインに残ります。我々は、(例えば、一緒にこれらの断片の全てを収集3-1+4-と、等)-joinの動作、CONCATENATE(暗黙的に文字列に変換される)、最終番号で、パイプそれにiex(の別名Invoke-Expressionとに類似eval)。


懸念は、呼び出し元が既に$ oa値(たとえば$ o = 999)を指定している場合、このエントリの式は正しい値を計算しないことです。このソリューションに$ oの初期化を追加する必要があります。
ベボ

@Bevoこれは、コマンドラインから実行される完全なスクリプトであり、関数や対話型シェルからではありません。私の提出物の大部分はそのようなものです。そのようなシナリオでは、心配する定義済みの変数がないため、コードが少し短くなる可能性があるからです。
AdmBorkBork


0

Japt -x21 19バイト

änJ f mÎí*Uò¦ ®ÎpZÊ

それを試してみてください


説明

                        :Implicit input of array U
  J                     :Prepend -1
än                      :Get deltas
    f                   :Filter (remove 0s)
      m                 :Map
       Î                : Signs
        í               :Interleave
          U             :  Original input
           ò            :  Partition on
            ¦           :   Inequality
              ®         :  Map each sub-array Z
               Î        :    Get first element
                p       :    Raise to the power of
                 ZÊ     :     Length of Z
         *              :Reduce each pair of elements by multiplcation
                        :Implicitly reduce by addition and output
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.