Sonuç almak için gereken işlemleri bulun


10

Yani görev basittir, sayı dizisi ve sonuç göz önüne alındığında, istenen sonucu elde etmek için diziden sayılarda hangi işlemleri kullanmanız gerektiğini bulmanız gerekir.

Başlamayı basitleştirelim ve sadece toplama, çıkarma, çarpma ve bölme gibi temel işlemlere izin verelim.

Misal:

Input  : [5,5,5,5,5] 100
Output : 5*5*5-5*5

Java gibi dillere bazı avantajlar sağlamak için, istek tüm programı değil işlevi uygulamaktır ve sonuç parametre ile döndürülebilir veya konsola yazdırılabilir.

Kod, miktar baytlarına göre puanlanır ve golf kodu meydan okuması olarak en düşük puan kazanır.

Diğer bir gerekliliktir Eğer dizi için sadece rakamlar içeriyorsa ek -10 puan alabilirsiniz , aşağıdaki rakamlardan rakamlar oluşturabileceğiniz destek çözümleri. yani

Input  : [1,2,3,4,5] 0
Output : 12-3-4-5

Çıktılar önerilen çıktılarsa, bazı durumlarda birden fazla çözüm olabileceğini unutmayın. Verilen görev için bir veya daha fazla çözüm sunacaksınız.

DÜZENLEME: Sonuç matematiksel açıdan geçerli olmalıdır, bu nedenle bölüm tamsayı değil rasyonel bölümdür ve işlem önceliği klasik matematik ile aynıdır (ilk çarpma ve bölme sonra toplama ve çıkarma).


4
Mu *ve /üzerinde precendence var +ve -? İki örneğiniz birbiriyle çelişiyor.
Leaky Nun

1
Lütfen, gelecekte java gibi bir dil için yüzde tabanlı ödüller oluşturduğunuzdan emin olun, -10 bayt jöle kadar iyi değildir
Bálint


4
Sayıların sırayla kullanılması gerekiyor mu? Ayrıca, bundan sonra zorluklar için ben yürekten kullanmanızı tavsiye Sandbox sorunların bu tür Main göndermeden önce ütülenir.
AdmBorkBork

2
@ mbomb007 bunların hiçbirinin kopyası değil. Bunlar rasgele sayısal girdilerdir ve yalnızca temel matematik işlemlerine izin verilir, gerçek programlar üretmeleri beklenmez.
Patrick Roberts

Yanıtlar:



4

Oracle SQL 11.2, 322 304 270 bayt

SELECT o FROM(SELECT REPLACE(SUBSTR(:1,1,1)||REPLACE(SYS_CONNECT_BY_PATH(a||SUBSTR(:1,LEVEL*2+1,1),','),','),'_')o,LEVEL l FROM(SELECT SUBSTR('+-*/_',LEVEL,1)a FROM DUAL CONNECT BY LEVEL<6)CONNECT BY LEVEL<LENGTH(:1)/2)WHERE:2=dbms_aw.eval_number(o)AND l>LENGTH(:1)/2-1;

: 1 basamak listesidir
: 2 aranan sonuçtur

Golf hariç:

SELECT o
FROM   (
         SELECT REPLACE(SUBSTR(:1,1,1)||REPLACE(SYS_CONNECT_BY_PATH(a||SUBSTR(:1,LEVEL*2+1,1),','),','),'_')o,LEVEL l 
         FROM ( -- Create one row per operator 
                SELECT SUBSTR('+-*/_',LEVEL,1)a FROM DUAL CONNECT BY LEVEL<6
              ) CONNECT BY LEVEL<LENGTH(:1)/2  -- Create every combination of operators, one per ','
)
WHERE :2=dbms_aw.eval_number(o)  -- filter on result = evaluation
  AND l>LENGTH(:1)/2-1           -- keep only expressions using every digits

4

TSQL (sqlserver 2016) 310 294 280 bayt

Çirkin kod yazmak için ne harika bir fırsat:

golfed:

DECLARE @ varchar(max)= '5,5,5'
DECLARE @a varchar(20) = '125'

,@ varchar(max)='';WITH D as(SELECT @a a UNION ALL SELECT STUFF(a,charindex(',',a),1,value)FROM STRING_SPLIT('*,+,./,-,',',')x,d WHERE a like'%,%')SELECT @+=a+','''+REPLACE(a,'.','')+'''),('FROM D WHERE a not like'%,%'EXEC('SELECT y FROM(values('+@+'null,null))g(x,y)WHERE x='+@b)

Çevrimiçi deneyin

Okunabilir: (sql'in 4/5'in 0 olmadığını kabul etmesi için ondalık noktasının (.) Eklenmesi ve aynısının kaldırılması gerekir - bunu test eden insanlar için iyi kaldırma)

DECLARE @a varchar(max)= '5,5,5'
DECLARE @b varchar(20) = '5'

,@ varchar(max)=''
;WITH D as
(
  SELECT @a a
  UNION ALL
  SELECT STUFF(a,charindex(',',a),1,value)
  FROM STRING_SPLIT('*,+,./,-,',',')x,d
  WHERE a like'%,%'
)
SELECT @+=a+','''+REPLACE(a,',','')+'''),('
FROM D
WHERE a not like'%,%'

EXEC('SELECT y FROM(values('+@+'null,null))g(x,y)WHERE x='+@b)

Bu çözüm aynı zamanda bu tür girdileri de işleyebilir:

Girdi: [1,2,3,4,5] 0 Çıktı: 12-3-4-5


3

JavaScript (ES6), 165 147 bayt

a=>o=>(c=[],i=c=>{for(j=0;!((c[j]?++c[j]:c[j]=1)%5);)c[j++]=0},eval(`while(eval(e=(a+'').replace(/,/g,(_,j)=>'+-*/'.charAt(c[~-j/2])))!=o)i(c);e`))

İç içe eval... güzel.

f=a=>o=>(c=[],i=c=>{for(j=0;!((c[j]?++c[j]:c[j]=1)%5);)c[j++]=0},eval(`while(eval(e=(a+'').replace(/,/g,(_,j)=>'+-*/'.charAt(c[~-j/2])))!=o)i(c);e`))
console.log(f([5,5,5,5,5])(100))
console.log(f([1,2,3,4,5])(0))
console.log(f([3,4])(0.75))
console.log(f([3,4,5,6])(339))


3

Python 3, 170 155 bayt

from itertools import*
def f(n,o):print({k for k in[''.join(map(str,sum(j,())))[1:]for j in[zip(x,n)for x in product('+-*/',repeat=len(n))]]if eval(k)==o})

Operatörlerin tüm olası siparişlerini içeren bir jeneratör oluşturun, bunları sayılarla birleştirin, ardından cevabı alana kadar değerlendirin.

https://repl.it/C2F5


2
Sen değiştirerek birkaç karakter kurtarabilecek ['+','-','*','/']ile '+-*/'; çünkü strings tekrarlanabilir olduğundan, bu sadece bir gibi davranın olacak arrayher öğe her karakter olmak stringsize şu anda sahip dizisi ile sağlanan gibi hareket edecektir böylece -.
nasonfish

2

Python, 195 186 bayt

İşte bunu yapmak için iğrenç bir yol.

def x(i,r):
 t=""
 from random import choice as c
 while True:
  for j in i:
   t+=str(j)
   if c([0,1]):t+="."+c("+-/*")
  t=t.strip("+-*/.")+"."
  v=eval(t)
  if v == r:print t
  t=""

İşlev x, örneğin a listve a result- argümanlarını kabul eder x([1,2,3,4,5], 15).

Program "+", "-", "*", or "/", her sayı arasına eklenip eklenmeyeceğini veya bir araya getirmemiz gerektiğini rastgele seçmeye başladığımız bir döngü başlatır . Bu, aslında permütasyonlardan geçip her kombinasyonu bulmak için her kombinasyonu denemekten daha özlü bir seçenek gibi görünüyordu ve çalıştırılması daha uzun sürmesine ve çok daha az verimli olmasına rağmen . (Neyse ki bu bağlamda bir endişe değil!)

Ayrıca "." gibi tamsayı yuvarlak işlemleri yapmaktan kaçının 6/4 = 1. Bu evalbizim ifademizdir ve sonucun beklediğimiz şeye eşit olup olmadığını belirler ve eğer öyleyse ifadeyi çıktılar.

Bu program asla çıkmaz - öldürülünceye kadar sürekli sonuç çıkarmaya devam eder.

DÜZENLEME 1 : Tek satırlık ififadelerin kullanılabileceği gereksiz yeni satırları kaldırın .


gerçekten komik bir uygulama. ama biraz daha bayt kaydetmek kolay Çevrimiçi deneyin! (176 bayt)
bobrobbob

2

Matlab, 234 238 258 bayt

Giriş dizisinin sayı sırasının fiat tarafından tutulduğu diğer cevapların sınırlamalarına dayanarak varsayıyorum.

n=length(x)-1
k=n*2+2
p=unique(nchoosek(repmat('*-+/',1,n),n),'rows')
p=[p char(' '*~~p(:,1))]'
c=char(x'*~~p(1,:))
o=p(:,r==cellfun(@eval,mat2cell(reshape([c(:) p(:)]',k,[]),k,0|p(1,:))))
reshape([repmat(x',size(o,2),1) o(:)]',k,[])'

Bu kod sayı dizisi alır x, demek x = '12345've bir sonuç r, demek r = 15ve iadeler ifadelerin dizeleri tüm almak için değerlendirebilir rgelen xdört operatörleri kullanarak.

ones(length())-Type veya repmat(length())-type ifadelerini kullanmaktan kaçınmak için iki farklı uzunluk eşdeğeri yol kullandım : ~~p(1,:)bu, not-not değerlerini döndürmez p(yani, 1ilk boyut olarak sam uzunluğunun listesi p) ve 0|p(:,1)0 veya orada döndürür -a-değer-in- p(yani, 1ikinci boyutuyla aynı uzunlukta bir liste p).

Matlab'ın bir nchoosek değiştirme yöntemi yok, bu yüzden operatörleri doğru sayıda kopyaladım, nchoosekdaha geniş operatör seçimi için tüm alanı hesapladım ve ardından uniquesonucu olması gerektiği şekilde çözümlemek için bir çağrı kullandım ('*** +' ve '*** +' gibi eşdeğer kombinasyonları kaldırmak). Birleştirme amacıyla giriş vektörünün uzunluğunu eşleştirmek için bir boşluk ekler ve ardından giriş dizeleri ile operatör dizelerini bir matrisin sütunlarına oluştururum. Daha sonra, sonuçları almak ve girdilerimizle eşleşen sonuçlarla bu sütunlara karşılık gelen işleçlerin sırasını bulmak için ifadeleri sütun olarak değerlendiririm r.

Test: x = '12345', r = 15:

1*2*3+4+5 
1+2+3+4+5 
1-2*3+4*5 

Eğer çift kesinlik değerleri bir dizi almak zorunda olsaydım , benim puan için x = num2str(x,'%d');21 (20 olmadan ;) ekleyerek, bir dizeye rakamları dönüştürmek gerekir . * Ekstra baytlar tamamen bıraktığım noktalı virgüllerdi, böylece bu kodu çalıştıran herkes komut dizisinin uzun dizilerle patlamasını görmeyecekti. Düzenlemem zaten mantıksal ve iki nokta üstüste işlenenlerle ilgili dev bir uyarı yığını ürettiğinden, yeni sürümdeki noktalı virgülleri kaldırdım.

Düzenleme 2: a 2*n+2ile değiştirmeyi unuttum k.

Eski cevap:

n=length(x)-1;
p=unique(nchoosek(repmat(['*','-','+','/'],1,n),n),'rows');
l=length(p);
p=[p repmat(' ',l,1)]';
c=reshape([repmat(x',l,1) p(:)]',n*2+2,[]);
o = p(:,r == cellfun(@eval, mat2cell(c,n*2+2,ones(l,1))));
reshape([repmat(x',size(o,2),1) o(:)]',n*2+2,[])'

2

JavaScript (ES6), 88 bayt

a=>o=>eval(`while(eval(e=(a+'').replace(/,/g,_=>'+-*/'.charAt(Math.random()*5)))!=o);e`)

Karışıma biraz rasgele attı. Kombinasyonlar aracılığıyla sistematik olarak yinelemekten çok daha kolay.

Test odası

f=a=>o=>eval(`while(eval(e=(a+'').replace(/,/g,_=>'+-*/'.charAt(Math.random()*5)))!=o);e`)
console.log(f([5,5,5,5,5])(100))
console.log(f([1,2,3,4,5])(0))
console.log(f([3,4])(0.75))
console.log(f([3,4,5,6])(339))


1

PHP, 108 bayt

for(;$i=$argc;eval("$s-$argv[1]?:die(\$s);"))for($s="",$x=$p++;--$i>1;$x/=4)$s.="+-*/"[$s?$x&3:4].$argv[$i];

Komut satırı bağımsız değişkenlerinden girişi ters sırada alır. İle çalıştırın -r.

Yıkmak

for(;                   # infinite loop:
    $i=$argc;               # 1. init $i to argument count
    eval("$s-$argv[1]?:"    # 3. if first argument equals expression value,
        ."die(\$s);")       #    print expression and exit
    )
    for($s="",              # 2. create expression:
        $x=$p++;            #    init map
        --$i>1;                 # loop from last to second argument
        $x/=4)                  # C: shift map by two bits
        $s.="+-*/"[$s?$x&3:4]   # A: append operator (none for first operand)
            .$argv[$i];         # B: append operand

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.