最少100オペレーション


15

概要

数字のリストが与えられたら、100にするための最も少ない操作を見つけます。

入力

数字の列。数字の順序である場合とない場合があります。数字の順序を変更することはできませんが、プラス(+)またはマイナス(-)演算子をそれぞれの間に追加して、合計が100になるようにすることができます。

出力

追加された演算子の数と、それに続く数字と演算子の完全なシーケンス。2つは、スペース、タブ、または改行で区切ることができます。

有効な

入力:123456789
出力:3 123–45–67+89

無効な
入力:123456789
出力:(
6 1+2+34-5+67-8+9
より少ない操作でこれを解決する方法があります)



すべての数字を使用する必要がありますか?+and のみを使用できます-か?100入力から常に作成できると想定できますか?
TheLethalCoder

6
さらにいくつかのテストケースが大歓迎です。
アーナウルド

2
最初の数字の前に記号を追加できないことを確認できますか?つまり、入力与えられ299399、う-299+399有効では?
ルイスメンドー

1
「0」は数字ですか?たとえば、「10808」は有効な入力ですか?「1 108-08」は有効な応答ですか?
チャスブラウン

回答:


10

JavaScript(ES6)、153 176バイト

編集:非厳密モードでは、JSは0で始まる数値式を8進数として解釈します(たとえば017、10進数で15として解析されます)。これは、先行ゼロをサポートする修正バージョンです。

let f =

s=>[...Array(3**(l=s.length,l-1))].map((_,n)=>m=eval((x=s.replace(/./g,(c,i)=>c+['','+','-'][o=(n/3**i|0)%3,j-=!o,o],j=l)).replace(/\b0+/g,' '))-100|j>m?m:(S=x,j),m=l)&&m+' '+S

console.log(f("123456789"))
console.log(f("20172117"))


ニース、入力として20172117はどうですか?
mdahmoune

@LuisMendo実際には、予想される答えはであると思います2-017-2+117。ただし017、JSの8進数表記であり、10進数で15になります。だから私の現在のコードは見つけるだけ2-0-17-2+117です。今日はその問題に対処しようとします。
アーナルド

@アーナウルドああ、私はその他の解決策を見ていませんでした。私のコメントを削除する
ルイスMendo

@mdahmouneこれを持ってきてくれてありがとう。修正されました。
アーナルド

3**(l=s.length,l-1)=>3**~-(l=s.length)
l4m2

5

MATL37 36バイト

n'+-'OhZ^!t2\s&SZ)"G@!vXzU100=?@z3M.

テストケースはTIOで約6秒かかります。

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

使い方

n        % Implicitly input a string. Number of elements, say k
'+-'     % Push this string
Oh       % Append char 0. This is treated like ' ' (space)
Z^       % Cartesian power of the three-char string '+- ' raised to k.
         % Gives a matrix where each row is a Cartesian k-tuple
!        % Transpose
t        % Duplicate
2\       % Modulo 2. This turns '+' and '-' into 1, and ' ' into 0
s        % Sum of each column: number of '+' and '-' symbols
&S       % Sort and push the indices of the sorting
Z)       % Apply as column indices. This sorts the columns (k-tuples)
         % by the number of '+' and '-' they contain
"        % For each column, i.e. each k-tuple formed by '+', '-' and ' '
  G      %   Push input string again
  @!     %   Push k-tuple as row vector (string)
  v      %   Concatenate vertically into a 2×k char array
  Xz     %   Remove space (and char 0). Gives a string as result. In this
         %   process, the 2×k array is linearized in column major order 
         %   (down, then across). So the '+' and '-' signs are between 
         %   digits of the input, or at the end
  U      %   Convert to number. This performs the operation determined by
         %   by the '+' and '-' signs and returns the result. A trailing
         %   '+' or '-' sign makes the input invalid, which causes an
         %   empty result
  100=   %   Is it equal to 100?
  ?      %   If so
    @    %     Push current k-tuple
    z    %     Number of nonzeros, i.e. of '+' and '-' signs
    3M   %     Push linearized string without spaces again
    .    %     Break for loop
         %   Implicit end
         % Implicit end
         % Implicitly dispplay stack

入力として299399はどうですか?
mdahmoune

1
@mdahmouneに299399は解決策がないため、有効な入力ではありません(桁間を移動するように演算子が指定されたため、その入力には桁間でない-299+399場所が必要です-)。
ジョナサンアラン

@mdahmoune記号を数字の間にのみ挿入できる場合(チャレンジテキストのとおり)、解決策はないと思います。最初の桁にも追加できる場合、解決策はです-299+399その場合、コードを少し変更する必要があります。OPに説明を求めました
ルイスメンドー

また、注目に値するのは、前後の両方である場合、例123456789の演算子カウントは4notである必要があること3です。
ジョナサンアラン

@mdahmoune OPは、符号は数字の間のみにできることを確認しました。だから、私のコードは正しく299399、無効な入力です。なぜなら、OPも明らかにしたように、すべての入力には少なくとも1つの解決策が必要だからです
ルイスメンドー

3

[Python 2]、164 158バイト

from itertools import*
f=lambda N:min((len(s)-len(N),s)for s in(''.join(sum(zip(N,p+('',)),()))for p in product(('+','-',''),repeat=len(N)-1))if eval(s)==100)

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

Nを数字列として使用します。タプル(numOps、expressionString)を返します。

基本的に他と同じアプローチ。itertools.productを使用して個々の「ケース」を作成します。たとえば、N == '1322'の場合、「ケース」は('-','','+')となり、「1-32 + 2」を評価します。

入力が無効な場合はValueErrorをスローします(ただし、OPは無効な入力を保証していないと思います)。


3

PHP、166 171バイト

for(;$n<3**$e=strlen($x=$argn);eval("return $s;")-100?:$r[]=sprintf("%2d $s",strlen($s)-$e))for($i=0,$s="",$k=$n++;a&$c=$x[$i];$k/=3)$s.="+-"[$i++?$k%3:2].$c;echo min($r);

でパイプとして実行する-nR、オンラインでテストします

フォーマットされた数値を使用して結果をソートします->
先行ブランクを印刷する場合があります(また、99桁を超える入力では失敗する場合があります%2d。修正するために数値を増やしてください)。

10桁以下、161バイト

for(;$n<3**$e=strlen($x=$argn);eval("return $s;")-100?:$r[]=(strlen($s)-$e)." $s")for($i=0,$s="",$k=$n++;a&$c=$x[$i];$k/=3)$s.="+-"[$i++?$k%3:2].$c;echo min($r);

壊す

for(;$n<3**$e=strlen($x=$argn); # loop $n up
    eval("return $s;")-100?:        # 2. evaluate term, if 100 then
                                    # prepend number of operations, add to results
        $r[]=sprintf("%2d $s",strlen($s)-$e)
)
                                # 1. create term
    for($i=0,$s="",$k=$n++;         # init variables, increment $n
        a&$c=$x[$i];$k/=3)          # loop through digits/operator index
        $s.="+-"[$i++?$k%3:2].$c;   # prepend operator for base-3 digit (nothing for 2)
echo min($r);                   # print lowest result

3

ゼリー、32 バイト

L’⁾+_ṗż@€
ŒṖÇ€ẎµFV=ȷ2µÐfLÞḢFṄḟ³L

_代わりに-)Jellyオペレーターを使用して表示する完全なプログラム。

注:表示するには-、出力ではなく、_(要件ではありません)を追加⁾_-yF(は⁾_-文字のペアリテラルである['_','-']yアトム「を翻訳し」二項です)。

どうやって?

L’⁾+_ṗż@€ - Link 1, form all sums from a partition: list of lists of characters
                                     e.g. ["12","345","67"]
L         - length                        3
 ’        - decremented                   2
  ⁾+_     - literal ['+','_']
     ṗ    - Cartesian power               ["++","+_","_+","__"]
      ż@€ - zip for €ach (swap @rguments) ["12+345+67","12+345_67","12_345+67","12_345_67"]

ŒṖÇ€ẎµFV=ȷ2µÐfLÞḢFṄḟ³L - Main link: list of characters
ŒṖ                     - all partitions
  Ç€                   - call the last link (1) as a monad for €ach
    Ẏ                  - tighten (flatten by 1 level)
     µ     µÐf         - filter keep if:
      F                -   flatten
       V               -   evaluate as Jelly code (perform the sum)
         ȷ2            -   literal 100
        =              -   equal?
               Þ       - sort by:
              L        -  length
                Ḣ      - head
                 F     - flatten
                  Ṅ    - print that and a newline
                   ḟ³  - filter out the characters from the input
                     L - length (number of operators)
                       - implicit print

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


2

Mathematica、136 146 149 156 165 166 バイト

#&@@Sort[{StringLength@#-e+9!(ToExpression@#-100)^2,#}&/@StringJoin/@(Riffle[b,#]&)/@Tuples[{"","+","-"},(e=Length[b=Characters@#])-1]]&

{3, 123-45-67+89}たとえば戻ります。

テストケースの完了には約0.09秒かかります。


2

Pythonの2256 230 208 205 172 171 170 165バイト、反復法

  • 33 Chas Brownに感謝
  • 交換時に一つは、バイトを保存するlen(a)ことにより、w
  • 交換時に一つは、バイトを保存するz-=1;d=zことにより、d=z=z-1
q=[];a=input()
w=len(a);z=n=3**w
while z-n/3:
 d=z=z-1;j=0;b=''
 while d:r=d%3;d/=3;b+=a[j]+chr(r+43)*(d>0!=r-1);j+=1
 if eval(b)==100:q+=[(len(b)-w,b)]
print min(q)

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

簡単な説明 コードは、ベース3の表現を使用して、可能なすべての組み合わせに従って、演算子{'+'、 '-'、concatenation}で数字をインターリーブします。

Python 2、167バイト、再帰的メソッド

def f(s):
 if len(s)==1:return[s]
 b=s[0];q=[]
 for z in f(s[1:]):q+=[b+'+'+z,b+'-'+z,b+z]
 return q
a=input()
print min((len(x)-len(a),x)for x in f(a)if eval(x)==100)

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

いくつかの出力

"399299"    --> (1, '399-299')
"987654321" --> (4, '98-76+54+3+21')
"1111111"   --> (3, '1+111-1-11')

1
divmodの使用が好きです!私が見ることができるいくつかのゴルフ:文字列はすでに6バイトを節約するために反復可能であるため、list(input())just input()に置き換えます。と置き換えb.count('+')+b.count('-')len(b)-len(a)12バイトを節約します。で置き換えchr(r+43)chr(r+43)*(d>0!=r-1)から、行b=b[:-1].replace(',','')を削除してネット15バイトを節約できます((d>0!=r-1)と同等です(d>0 and 0!=r-1))。
チャスブラウン

2

Brachylog、36バイト

~cịᵐ{|ṅ}ᵐ{+100&{ℕṫ,"+"↻|ṫ}ᵐcbE&kl;E}

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

ただし、その半分以上は出力形式を正しく取得することです。実際のコアロジックは次のとおりです。

15バイト

~cịᵐ{|ṅ}ᵐ.+100∧

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

これは、[123、–45、–67,89]のようなリストを返します。式は要素の合計であり、演算子の数はリストの長さより1少ない数です。

~cLhℕ∧100~+Lほぼ12バイトで動作します(オンラインで試してみてください!)-しかし、TIOで9桁の完全な入力を処理するに10808は遅すぎます。さらに重要なことは、次のような入力に対して失敗することです。t [108、-08]パーティションを参照してください。


1

Haskell180 178バイト

m#[a]=[[a]]
m#(b:r)|s<-m#r=m(b:)=<<[s,m('+':)s,m('-':)s]
o '-'=(-)
o _=(+)
(p:r)?a|[(b,s)]<-lex r=s?o p a(read b)
_?a=a
g s=minimum[(sum[1|c<-t,c<'0'],t)|t<-map#s,('+':t)?0==100]

オンラインでお試しください!使用法:g "123456789"yields (3,"123-45-67+89")

#考えられるすべての用語のリストを作成し、用語を評価し、100と?評価される用語をgフィルター処理して、オペランドの数が最小のものを返します。


0

ゼリー、27バイト

L’““+“_”ṗ⁸żF¥ⱮV⁼ȷ2ƊƇLÞḢṄḟ⁸L

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

ジョナサン・アランの古い答えからいくつかのヒントを受け取らなかったとは言えません。;-)

彼の答えと比較すると、言語の更新のために比較を公平にすると、これは5バイトではなく2バイト短くなります(30)。

L’““+“_”ṗ⁸żF¥Ð€V⁼ȷ2$$ÐfLÞḢṄḟ⁸L

他の方法(古いバージョンではなく新しいバージョン)を比較すると、違いは同じです(以下に示すように、29バイトになります)。

ŒṖżⱮL’⁾+_ṗƲ$€ẎFV=ȷ2ƲƇLÞḢFṄḟ³L
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.