Çok güzel Friedman numaraları


13

Bir Friedman Numarası , +, -, *, /, ^, parantez ve birleştirme işlemleriyle birlikte kendi basamaklarını kullanan önemsiz olmayan bir ifadeye eşit olan pozitif bir tamsayıdır.

Güzel Bir Friedman Numarası, kendi basamaklarını aynı işlemlerle birlikte, basamakları orijinal sıralarında kullanan önemsiz olmayan bir ifadeye eşit olan pozitif bir tamsayıdır.

Burada icat ettiğim çok güzel bir Friedman sayısı (VNFN), böyle bir ifadenin daha az güzel (bence) kısımları olmadan yazılabilen bir Nice Friedman Numarasıdır. Parantez, birleştirme ve tek taraflı olumsuzlama kabul edilmez.

Bu meydan okuma için, parantez olmadan bir ifade yazmanın üç olası yolu vardır.

Önek: Bu, sol çağrışımla eşdeğerdir. Bu ifade türü, rakamların solundaki tüm işleçlerle birlikte yazılır. Her operatör aşağıdaki iki ifadeye uygulanır. Örneğin:

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

Bu şekilde yazılabilen bir VNFN 343'tür:

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

Postfix: Bu sağ çağrışımla eşdeğerdir. İşlemin rakamların sağına gitmesi dışında, önek gösterimi gibidir. Her işleç, önceki iki ifade için geçerlidir. Örneğin:

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

Bu şekilde yazılabilen bir VNFN 15655'tir:

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

Infix: Infix gösterimi, beş işlem için standart işlem sırasını kullanır. Mücadelenin amaçları doğrultusunda, bu işlem sırası aşağıdaki gibi tanımlanacaktır: ^Önce parantez boyutunu , sağa doğru ilişkilendirin. Ardından, parantez içine alın *ve /aynı anda birlikte bırakın. Son olarak, parantez içinde +ve -aynı anda, birlikte bırakılır.

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

Bu şekilde yazılabilen bir VNFN 11664'tür:

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

Zorluk: Pozitif bir tamsayı verildiğinde, önek, infix veya postfix gösterimlerinde kendi rakamlarının önemsiz olmayan bir ifadesi olarak ifade edilebilirse, bu ifadeyi çıktılayın. Değilse, hiçbir şey çıktı.

Açıklamalar: Birden fazla gösterim mümkünse, bunların boş olmayan alt kümelerini çıktılayabilirsiniz. Örneğin, 736 bir VNFN'dir:

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

+^736, 7+3^6Ya da her ikisi, tüm olarak kabul edilebilir bir çıkışı olacaktır.

"Önemsiz" ifade, herhangi bir operatör kullanmayan ifade anlamına gelir. Bu yalnızca bir basamaklı sayılarla ilgilidir ve bir basamaklı sayılar VNFN olamaz. Bu bir Friedman Numarası tanımından miras alınır.

Cevaplar bir milyonun altındaki girdilerde saniye veya dakika olarak çalışmalıdır.

İlişkili.

IO: Standart IO kuralları. Tam program, fonksiyon, fiil veya benzeri. STDIN, komut satırı, işlev bağımsız değişkeni veya benzeri. "Hiçbir şey" çıktısı için, boş dize, boş bir çizgi nullveya benzeri ve boş bir koleksiyonun tümü iyi durumdadır. Çıktı, bir temsilde bulunamayan bir karakterle ayrılmış bir dize olabilir veya bir dize koleksiyonu olabilir.

Örnekler:

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

Puanlama: Bu kod golfü. En az bayt kazanır.

Ayrıca, bir tane bulursanız, lütfen cevabınıza yeni bir Çok Güzel Friedman Numarası verin.


*(+(*(1,2),3,4)sonra bir yakın paren eksik,3
Sparr

"Saniye veya dakika cinsinden" sınırı nedir? Dört saat hala ... çok ... dakika.
Charles

@NotthatCharles 4 saat çok fazla. Diyelim ki kıpır kıpır bir oda ile makinemde 1 saat. Çok basamaklı sayılar hakkında, birleştirme ile Parentheses, concatenation and unary negation are disallowed.
bahsettiğim şey budur

Yanıtlar:


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

İle ara perl -M5.10.0 scratch.pl 736


Sonuçlar

Bulduğum ilk birkaç sonuç:

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

açıklama

Tamamen rahat

Daha sonraki golfü kolaylaştırmak için kendimi mümkün olduğunca tekrarlamaya çalıştım.

#!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

Nasıl golf oynuyor

  • Boşluğu ve yorumları kaldırın ve tüm değişkenleri 1 karakterlik sürümle değiştirin
  • Programı içine sar $_=q! ... !;eval
  • Dizeleri ayıklayın ve daha sonra değiştirin.

Bu, sonuç için satır sonlarını kaldırabileceğiniz böyle bir şey verir:

$_='
    $_=$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

Cevabınız için teşekkürler ve ilk etapta olduğunuz için tebrikler. Geniş grevlerde nasıl çalışır?
isaacg

Perl bilmiyorum, ama 3 kez meydana gelip }globbazı baytları kurtarmak mümkün gibi görünüyor .
isaacg

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

Lanet olsun, çok yakın.
isaacg

4

Yakut 2.1.5 only - 213 220 238 + 9 = 247

Ruby'nin Perl'i nasıl attığından emin değilim, ama işte gidiyorsun ...

Bunu -rtimeout bayrağıyla çalıştırın (ve -W0 veya stderr'ınızı başka bir yere gönderin).

Bu hale getirmek için biraz daha sağlam yerini send([].methods[81],z-1)ile repeated_permutation(z-1)ekstra bir karakter ve puan (yani 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)]}

Temel olarak, operatörlerin tüm permütasyonlarını gözden geçirin ve bu sırayla infix, postfix ve öneki deneyin. dYöntem kullanımları evalikinci parametre herhangi DivideByZero veya taşma durumları yakalamak, hesaplamaları gerçekleştirmek için.

Bununla birlikte, / dev / null'a stderr göndermeniz gerekir, aksi evaltakdirde bazen gibi uyarılar yazdırılır (eval):1: warning: in a**b, b may be too big.

Bu ungolfing ile geldim, üç karakter kurtarmak için bir yol buldum!

Ungolfed (modası geçmiş ancak benzer ilkeler):

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))
}

Değişiklikler

247 bu işi zaman aşımı yerine daha büyük sayılar için yaptı.

220 , paren dizileri bildirerek üç karakteri tıraş etti ve tek haneli sayıların VNFN'ler olarak kabul edildiği bir hatayı düzeltti.

213 ilk taahhüt


Harika bir çözüm - benim için tam bir kara büyü! Yerleşik zip ve permütasyon fonksiyonları olduğu için yakut Perl'i atıyor sanırım.
alexander-brett

@ alexander-brett daha iyi mi? a.zip(b,c)gibi bir dizi dizisi döndürür [ [a[0],b[0],c[0]],[a[1],b[1],c[1]], etc.]ve ['hi', 'there']*''sadece dizi değerlerinin dize olarak temsil edilmesini birleştirir.
Charles

oh, ve [a,b]*3verim[a,b,a,b,a,b]
Charles değil

1

MATLAB (435 b)

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

burada dene

http://octave-online.net/


daha fazla iyileştirme gerekiyor
Abr001am

insanlar burada matlab ile alışkanlık değil mi?
Abr001am

0

Python 2, 303 bayt

Çevrimiçi deneyin

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 çıkışı **bunun yerine içerecektir ^. Buna izin verilmezse, .replace('**','^')gerçekleşir ve 18 bayt daha eklenir

Açıklama:

# 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.