Дуже приємні номери Фрідмана


13

Фрідман Число є позитивним цілим числом, що дорівнює нетривіальною вираз , яке використовує свої власні цифри в поєднанні з операціями +, -, *, /, ^, круглі дужки і конкатенації.

Число Ніцца Фрідмана - це додатне ціле число, яке дорівнює нетривіальному виразу, яке використовує власні цифри в поєднанні з тими ж операціями, з цифрами у їх первісному порядку.

Дуже приємний номер Фрідмана (VNFN), який я тут вигадую, - це число Ніцца Фрідмана, яке можна записати без менш симпатичних (на мою думку) частин такого виразу. Дужки, конкатенація та одинарне заперечення заборонені.

Для цього завдання є три можливі способи написання виразу без дужок.

Приставка: це еквівалентно лівій асоціативності. Цей тип вираження записується всіма операторами зліва від цифр. Кожен оператор застосовує до наступних двох виразів. Наприклад:

*+*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

Infix: Позначення Infix використовує стандартний порядок операцій для п'яти операцій. Для цілей виклику цей порядок операцій буде визначений наступним чином: ^Перше впорядковувати , правильно асоціативно. Потім дужки *та /одночасно залишають асоціативно. Нарешті, круглі дужки +та -одночасно залишаються асоціативно.

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. Це успадковане із визначення числа Фрідмана.

Відповіді повинні тривати за лічені секунди або хвилини на входах менше мільйона.

Пов'язані.

IO: Стандартні правила IO. Повна програма, функція, дієслово тощо. STDIN, командний рядок, аргумент функції або подібне. Для виведення "нічого" порожній рядок, порожній рядок 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

Оцінка: Це гольф з кодом. Виграє найменше байт.

Крім того, якщо ви знайдете його, будь ласка, вкажіть новий дуже хороший номер Фрідмана у своїй відповіді.


*(+(*(1,2),3,4)відсутній один близький батько, після,3
Спарр

Який ковпачок "у секундах чи хвилинах"? Чотири години все ще в .... багато ... хвилин.
Не те, що Чарльз

@NotthatCharles 4 години - це занадто багато. Скажімо, 1 годину на моїй машині, в якійсь кімнаті, що хитається. Про багатоцифрові цифри, це те, про що я Parentheses, concatenation and unary negation are disallowed.
хотів сказати, об'єднавшись

Відповіді:


5

Perl, 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

Як це гольф

  • Видаліть пробіли та коментарі та замініть всі варіанти на 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-> 15В; }glob}glob}glob-> 15B :)
Олександр-Бретт

Дарн, так близько.
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 або переповнення.

Вам потрібно надіслати stderr в / dev / null, хоча інакше evalіноді надрукуються попередження на зразок (eval):1: warning: in a**b, b may be too big.

Поки я придумав це нерозіграння, я знайшов спосіб врятувати три символи!

Недоліковані (застарілі, але схожі принципи):

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 відголив три знаки, оголосивши батьківські масиви, і виправив помилку, коли одноцифрові числа вважалися VNFN

213 початкові коміти


Прекрасне рішення - повна чорна магія для мене! Я думаю, що рубін перемагає Perl, оскільки у нього є вбудовані функції блискавки та перестановки.
Олександр-Бретт

@ 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

МАТЛАБ (435 б)

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

люди тут не звичні з матлабом?
15001

0

Python 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

Вихід Infix буде містити **замість ^. Якщо це заборонено, .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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.