아주 좋은 Friedman 번호


13

프리드만 번호 , *, /, ^ 괄호와 연결 - 동작 +와 결합하여 자신의 숫자를 사용하는 비 단순 발현와 동일한 양의 정수이다.

Nice Friedman Number는 고유 한 숫자를 원래 순서대로 숫자와 동일한 연산과 함께 사용하는 사소한 표현과 같은 양의 정수입니다.

내가 여기서 발명하고있는 Very Nice Friedman Number (VNFN)는 그러한 표현의 덜 예쁘지 않은 부분으로 쓰여질 수있는 Nice Friedman Number입니다. 괄호, 연결 및 단항 부정은 허용되지 않습니다.

이 문제를 해결하기 위해 괄호없이 표현식을 작성하는 세 가지 방법이 있습니다.

접두사 : 왼쪽 연관과 동일합니다. 이 유형의 표현식은 모든 연산자와 함께 숫자 왼쪽에 작성됩니다. 각 연산자는 다음 두 표현식에 적용됩니다. 예를 들어 :

*+*1234 = *(+(*(1,2),3),4) = (((1*2)+3)*4) = 20

이런 식으로 쓸 수있는 VNFN은 343입니다.

^+343 = ^(+(3,4),3) = ((3+4)^3) = 343

접미사 : 이것은 오른쪽 연관과 같습니다. 연산이 숫자의 오른쪽으로 이동한다는 점을 제외하면 접두사 표기법과 같습니다. 각 연산자는 두 개의 이전 표현식에 적용됩니다. 예를 들어 :

1234*+* = (1,(2,(3,4)*)+)* = (1*(2+(3*4))) = 14

이런 식으로 쓸 수있는 VNFN은 15655입니다.

15655^+** = (1,(5,(6,(5,5)^)+)*)* = (1*(5*(6+(5^5)))) = 15655

접두사 : 접두사 표기법은 5 가지 작업에 표준 작업 순서를 사용합니다. 당면 과제의 목적을 위해 해당 작업 순서는 다음과 같이 정의됩니다 ^. 그런 다음, 괄호로 */동시에 연관 떠났다. 마지막으로, 괄호로 +-동시에 연관 떠났다.

1-2-3 = (1-2)-3 = -4
2/3*2 = (2/3)*2 = 4/3
2^2^3 = 2^(2^3) = 256
1^2*3+4 = (1^2)*3+4 = 7

이 방법으로 쓸 수있는 VNFN은 11664입니다.

1*1*6^6/4 = (((1*1)*(6^6))/4) = 11664

도전 과제 : 양의 정수가 주어지면 접두사, 접두사 또는 접미사 표기법으로 고유 한 자릿수가 아닌 간단한 표현으로 표현할 수 있으면 해당 표현식을 출력하십시오. 그렇지 않으면 아무것도 출력하지 않습니다.

설명 : 여러 표현이 가능한 경우 비어 있지 않은 부분 집합을 출력 할 수 있습니다. 예를 들어, 736은 VNFN입니다.

+^736 = 736
7+3^6 = 736

+^736, 7+3^6또는 둘 모두를 출력으로 허용 할 것이다.

"Trivial"식은 연산자를 사용하지 않는 식을 의미합니다. 이는 한 자리 숫자에만 해당되며 한 자리 숫자는 VNFN이 될 수 없습니다. 이것은 Friedman Number의 정의에서 상속됩니다.

답변은 백만 미만의 입력에서 몇 초 또는 몇 분 안에 실행되어야합니다.

관련.

IO : 표준 IO 규칙. 전체 프로그램, 기능, 동사 또는 유사. STDIN, 명령 행, 함수 인수 또는 유사 "Nothing"을 출력하는 경우 빈 문자열, 빈 줄 null또는 이와 유사한 항목 및 빈 컬렉션이 모두 적합합니다. 출력은 표현할 수없는 문자로 구분 된 문자열이거나 문자열 모음 일 수 있습니다.

예 :

127
None

343
^+343

736
736^+
7+3^6

2502
None

15655
15655^+**

11664
1*1*6^6/4
1^1*6^6/4

5
None

득점 : 이것은 코드 골프입니다. 가장 적은 바이트가 이깁니다.

또한 하나를 찾으면 답변에 새로운 Very Fried Friedman Number를 부여하십시오.


*(+(*(1,2),3,4)후 하나의 가까운 paren이 없습니다,3
Sparr

"초 또는 분 단위"의 상한선은 무엇입니까? 4 시간은 여전히 ​​.. 많은 ... 분입니다.
찰스

@NotthatCharles 4 시간이 너무 깁니다. 위 글룸이있는 내 컴퓨터에서 1 시간을 가정 해 봅시다. 여러 자리 번호에 대한, 즉 '나는에서 연결에 의해 다스 려 한거야Parentheses, concatenation and unary negation are disallowed.
isaacg

답변:


5

345 334 318 293 263 245B

$_='$_=$i=pop;$c=y///c-1;sub f{say if$c&&$i==eval pop=~s/\^/**/gr}A$m)$1$4"})};f"("x$c.$m}globOx$c.$i;A$1$4($m"})};f$m.")"x$c}glob$i.Ox$c;map{f$_}glob joinO,/./g';s!O!"{+,-,*,/,^}"!g;s!A!'map{m{(\d)((?R)|(\d)(?{$m=$3}))(.)(?{$m="'!ge;s!d!D!;eval

와 전화 perl -M5.10.0 scratch.pl 736


결과

내가 찾은 처음 몇 가지 결과는 다음과 같습니다.

^+343
736^+
7+3^6
^+/3125
^+^3125
/^+-11664
/^--11664
1-1+6^6/4
/^++14641
^^++14641
1+5^6/1-8
1+5^6^1-8
1+5^6-2-2
1+5^6-2^2
1+5^6+2-4
1+5^6+4^2
-^+^16377
-^-+16377
/^+^16384
/^-+16384

설명

완전히 풀린

나는 나중에 골프를 쉽게하기 위해 가능한 한 많이 반복하려고 노력했다.

#!perl
use 5.10.0;

$_ = $input = pop;

# y///c counts characters in $_
$count = y///c - 1;

sub f {
    say if $count && $input == eval pop =~ s/\^/**/gr
}

# PREFIX
map {
    m{                            # Parses *^+1234
        (\D)                      # $1 = first symbol
        (
            (?R)                  # RECURSE
        |
            (\d)(?{               # $3 = first digit
                $match=$3
            })
        )
        (.)(?{                    # $4 = last digit
            $match="$match)$1$4"
        })
    }x;
    f "(" x $count . $match
}
    # glob expands '{0,1}{0,1}' into 00,01,10,11
    glob "{+,-,*,/,^}" x $count . $input;

# POSTFIX
map {
    m{(\d)((?R)|(\d)(?{$match=$3}))(.)(?{$match="$1$4($match"})};
    f $match. ")" x $count
}
    glob $input . "{+,-,*,/,^}" x $count;

# INFIX
# /./g splits $_ into characters
map { f $_} glob join "{+,-,*,/,^}", /./g

골프는 어때?

  • 공백 및 주석을 제거하고 모든 var를 1 자 버전으로 바꿉니다.
  • 프로그램 포장 $_=q! ... !;eval
  • 문자열을 추출하고 나중에 대체하십시오.

결과와 같은 줄 바꿈을 제거 할 수있는 다음과 같은 내용이 표시됩니다.

$_='
    $_=$i=pop;
    $c=y///c-1;
    sub f{say if$c&&$i==eval pop=~s/\^/**/gr}
    A$m)$1$4"})};f"("x$c.$m}globOx$c.$i;
    A$1$4($m"})};f$m.")"x$c}glob$i.Ox$c;
    map{f$_}glob joinO,/./g
';
s!O!"{+,-,*,/,^}"!g;
s!A!'map{m{(\d)((?R)|(\d)(?{$m=$3}))(.)(?{$m="'!ge;
s!d!D!;
eval

답장을 보내 주셔서 감사합니다. 광범위한 파업에서 어떻게 작동합니까?
isaacg

나는 perl을 모른다. 그러나 3 개의 발생을 추출하고 }glob약간의 바이트를 저장 하는 것이 가능할 것 같다 .
isaacg

s!B!}glob!g;BBB-> 15B; }glob}glob}glob-> 15B :)
alexander-brett

대단해
isaacg

4

루비 2.1.5 만 - 213 220 238 + 9 = 247

루비가 펄을이기는 방법을 모르지만 여기에 있습니다.

이것을 -rtimeout 플래그와 함께 실행하십시오 (그리고 -W0 또는 stderr을 다른 곳으로 보내십시오).

이하려면 약간 더 강력한 대체 send([].methods[81],z-1)repeated_permutation(z-1)추가 문자 및 점수 (그래서, 248 ).

g=$*[0].split //
exit if 2>z=g.size
d=->a,s{$><<a*''&&exit if$*[0].to_i==timeout(2){eval"#{(s*'').gsub(?^,'**')}"}rescue p}
l,r=[?(]*z,[?)]*z
%w{* / + - ^}.send([].methods[81],z-1){|o|d[m=g.zip(o),m]
d[g+o,l.zip(m)+r]
d[o+g,l+g.zip(r,o)]}

기본적으로 연산자의 모든 순열을 살펴보고 순서대로 접두사, 접미사 및 접두사를 시도하십시오. 이 d메서드는 eval두 번째 매개 변수를 사용하여 계산을 수행하고 DivideByZero 또는 Overflow 예외를 포착합니다.

그러나 stderr을 / dev / null로 보내야 합니다. 그렇지 않으면 eval때때로와 같은 경고가 표시 (eval):1: warning: in a**b, b may be too big됩니다.

이 ungolfing을 생각해내는 동안 세 글자를 구할 수있는 방법을 찾았습니다!

언 골프 (오래되었지만 유사한 원칙) :

input = $*[0]
digits = input.split //
num_digits = digits.size
exit if 2 > num_digits # one-digit numbers should fail

def print_if_eval print_array, eval_array
  # concatenate the array and replace ^ with **
  eval_string = (eval_array * '').gsub(?^, '**') 
  val = eval(eval_string)
  if input.to_i == val
    $><<print_array*''
    exit
  end
rescue
  # this catches any DivideByZero or Overflow errors in eval.
end
# technically, this should be * (num_digits - 1), but as long as we 
# have AT LEAST (num_digits - 1) copies of the operators, this works
operators = %w{* / + - ^} * num_digits
left_parens = ['('] * num_digits
right_parens = [')'] * num_digits
operators.permutation(num_digits-1) { |op_set|
  # infix
  # just uses the native order of operations, so just zip it all together
  # 1+2-3*4/5^6
  print_if_eval(digits.zip(op_set),
                digits.zip(op_set))

  # postfix
  # leftparen-digit-operator, repeat; then add right_parens
  # (1+(2-(3*(4/(5^(6))))))
  # 
  print_if_eval(digits+op_set,
                (left_parens.zip(digits, op_set) + right_parens))

  # prefix
  # leftparens; then add digit-rightparen-operator, repeat
  # ((((((1)+2)-3)*4)/5)^6)
  print_if_eval(op_set+digits,
                left_parens + digits.zip(right_parens, op_set))
}

변경 로그

247 은 시간 초과 대신 더 많은 수의 작업을 수행했습니다.

220 은 paren array를 선언하여 3 개의 문자를 제거하고 한 자리 숫자가 VNFN으로 간주되는 버그를 수정했습니다.

213 초기 커밋


훌륭한 솔루션-나에게 완벽한 흑 마법! 루비에는 zip과 순열 함수가 내장되어 있기 때문에 Perl을 능가하는 것 같습니다.
alexander-brett

@ alexander-brett 더 나은가요? a.zip(b,c)같은 배열의 배열을 반환 [ [a[0],b[0],c[0]],[a[1],b[1],c[1]], etc.]하고 ['hi', 'there']*''단지 배열 값의 문자열 표현을 연결합니다.
찰스는

아, 그리고 [a,b]*3수율[a,b,a,b,a,b]
찰스가

1

MATLAB (435b)

n=input('');b=str2num(fliplr(num2str(n)));l=floor(log(b)/log(10));a=unique(nchoosek(repmat('*+-/^', 1,5), l), 'rows');for k=1:numel(a(:,1)),for j=0:2,c=strcat((j>1)*ones(l)*'(',mod(b,10)+48);for i=1:l,c=strcat(c,a(k,i),(j<1)*'(',mod(floor(b/10^i),10)+48,(j>1)*')'); end,c=strcat(c,(j<1)*ones(l)*')');if eval(c(1,:))==n,fprintf('%s%s%s%s\n',c(1,1:(j==1)*numel(c(1,:))),fliplr(a(k,1:(j>1)*l)),(j~=1)*num2str(n),a(k,1:(j<1)*l));end,end,end

여기서 해봐

http://octave-online.net/


여전히 더 많은 개선이 필요
Abr001am

사람들은 여기 matlab에 습관적이지 않습니까?
Abr001am

0

파이썬 2, 303 바이트

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

from itertools import*
n=input()
l=len(n)-1
E=eval
for c in product('+-*/^',repeat=l):
 L=lambda x,y:x.join(map(y.join,zip(n,c+('',)))).replace('^','**')
 C=''.join(c)
 try:
    if`E(L('',''))`==n:print L('','')
    if`E('('*-~l+L('',')'))`==n:print C[::-1]+n
    if`E(L('(','')+')'*l)`==n:print n+C
 except:pass

접두사 출력에 **대신 이 포함 됩니다 ^. 이것이 허용되지 않으면, 발생 .replace('**','^')하고 18 바이트를 더 추가하십시오

설명:

# get all possible combinations of operators (with repetitions)
product('+-*/^',repeat=l)  

# create string from input and operators like
# if passed '(' and '' will return (a+(b+(c
# if passed '' and ')' will return a)+b)+c)
# if passed '' and '' will return a+b+c
lambda x,y:x.join(map(y.join,zip(n,c+('',)))).replace('^','**')

# evaluate infix
E(L('',''))
# evaluate prefix
E('('*-~l+L('',')')) 
# evaluate postfix
E(L('(','')+')'*l)
# all evals need to be inside try-except to handle possible 0 division

# prefix output is need to be swapped (which IMO is not needed)
n:print C[::-1]+n
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.