100까지 가장 적은 작업


15

개요

자릿수 목록이 주어지면 100을 만드는 가장 적은 연산을 찾으십시오.

입력

숫자 순서 일 수도 있고 아닐 수도있는 숫자 문자열. 숫자의 순서는 변경할 수 없지만 더하기 (+) 또는 빼기 (-) 연산자를 사이에 더하여 총 합이 100이되도록 할 수 있습니다.

산출

추가 된 연산자 수와 전체 숫자 및 연산자 순서가 뒤 따릅니다. 공백, 탭 또는 줄 바꿈 순서로 두 개를 분리 할 수 ​​있습니다.

유효한

입력 : 123456789
출력 :3 123–45–67+89

유효하지 않은
입력 : 123456789
출력 :
6 1+2+34-5+67-8+9
(더 적은 작업으로이를 해결하는 방법이 있습니다)



모든 숫자를 사용해야합니까? 우리는 사용할 수 +-? 100입력으로 항상 만들 수 있다고 가정 할 수 있습니까 ?
TheLethalCoder

6
더 많은 테스트 사례가 매우 환영받을 것입니다.
Arnauld

2
첫 번째 숫자 앞에 부호를 붙일 수 없음을 확인할 수 있습니까? 즉, 입력 주어 299399, 것 -299+399유효?
Luis Mendo

1
'0'은 숫자입니까? 예를 들어, '10808'은 유효한 입력입니까? '1 108-08'이 ​​유효한 응답입니까?
Chas Brown

답변:


10

자바 스크립트 (ES6) 153 176 바이트

편집 : 엄격하지 않은 모드에서 JS는 0 접두사 숫자 표현식을 8 진수 017로 해석합니다 (예 : 10 진수로 15로 구문 분석 됨). 이것은 선행 0을 지원하는 고정 버전입니다.

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입니다. 그러나 017JS의 8 진수 표기법은 십진수 15입니다. 따라서 현재 코드는 2-0-17-2+117. 오늘 나중에 그 문제를 해결하려고 노력할 것입니다.
Arnauld

@ Arnauld 아, 나는 그 다른 해결책을 보지 못했습니다. 내 댓글 제거
Luis Mendo

@mdahmoune 이것을 가져 주셔서 감사합니다. 이제 수정되었습니다.
Arnauld

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

5

MATL , 37 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위치를 요구합니다 -).
Jonathan Allan

@mdahmoune 숫자가 챌린지 텍스트에 표시된 것처럼 숫자 사이 에만 부호를 삽입 할 수 있다면 해결책이 없다고 생각합니다. 첫 번째 자릿수 앞에 붙일 수 있으면 해결책이 -299+399있으며,이 경우 코드를 약간 변경 해야 합니다 . 설명을 위해 OP에 요청했습니다
Luis Mendo

또한이 전에 두 될 예정이었던 경우에 주목할만한 사이 다음 예제 123456789의 오퍼레이터 수 있어야 4하지 3.
Jonathan Allan

@mdahmoune OP는 부호가 숫자 사이에만있을 수 있음을 확인했습니다. 따라서 내 코드는 정확하고 299399유효하지 않은 입력입니다. OP가 명확하게 설명했듯이 모든 입력에는 적어도 하나의 솔루션이 있어야합니다.
Luis Mendo

3

[파이썬 2], 164158 바이트

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'의 경우 "case"는 ('-','','+')'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 연산자를 사용하여 표시되는 전체 프로그램입니다 ( _대신 -).

참고 : (필수 아님) -대신 출력에 표시하려면 and 사이를 _추가하십시오 ( 문자 쌍 리터럴 이며 2 진 "번역"아톰).⁾_-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

매스 매 티카, 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

파이썬 (2) , 256 (230) 208 205 172 171 170 165 바이트 반복법

  • 33 개 차스 브라운 덕분에
  • 교체 할 때 하나는 바이트를 저장 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}으로 인터리브합니다.

파이썬 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)).
Chas Brown

2

Brachylog , 36 바이트

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

온라인으로 사용해보십시오!

이 중 절반 이상이 출력 형식을 올바르게 얻는 것입니다. 실제 핵심 논리는 다음과 같습니다.

15 바이트

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

온라인으로 사용해보십시오!

[123, –45, –67,89]와 같은 목록이 반환됩니다. 표현식은 요소의 합이며 연산자 수는 목록 길이보다 1이 적습니다.

~cLhℕ∧100~+L거의 12 바이트 (작동 ! 온라인 체험 ) -하지만 TIO에서 전체 9 자리 숫자 입력을 처리하기 위해 너무 느린, 그리고 더 중요한 것은이 같은 입력 실패 10808'Brachylog는 앞에 0을 가지고 분할 숫자에 너무 똑똑하다, 아무튼 그래서 - [108, -08] 파티션을 참조하십시오.


1

하스켈 , 180 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"수익률 (3,"123-45-67+89").

#가능한 모든 용어의 목록을 작성하고, 용어를 평가하고, 100으로 ?평가되는 용어를 g필터링하고 최소 피연산자 수를 가진 단어를 반환합니다.


0

젤리 , 27 바이트

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

온라인으로 사용해보십시오!

Jonathan Allan의 오래된 답변에서 힌트를 얻지 못했다고 말할 수는 없습니다. ;-)

그의 답변과 비교할 때, 언어 업데이트로 인해 비교를하면이 하나는 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.