Diziyi Matematik Problemine Dönüştürün


35

Olumsuz olmayan tam sayıların saygısız bir listesi göz önüne alındığında, yeniden yazmayı aritmetik bir sorun olarak düşünün:

  • +Soldan sağa doğru artan sayı çiftleri arasına bir artı işareti ( ) eklenir (aka listenin başlangıcından sonuna kadar).
  • -Soldan sağa doğru azalan sayı çiftleri arasına eksi işareti ( ) eklenir.
  • *Eşit sayıların arasına çarpma işareti ( ) eklenir.

Başka bir yolla: herhangi bir alt liste a,b, a+beğer a<b, a-beğer a>bve a*beğer olur a==b.

Örneğin, liste

[12, 0, 7, 7, 29, 10, 2, 2, 1]

ifade olur

12 - 0 + 7*7 + 29 - 10 - 2*2 - 1

hangi için değerlendirir 75 .

Böyle bir listede yer alan ve onu değerlendiren, sonucu yazdıran veya iade eden bir program veya işlev yazın.

  • İşlem sırası önemlidir. Çarpma herhangi bir toplama veya çıkarma işleminden önce yapılmalıdır.
  • Giriş listesinin bir numarası varsa, değerlendirdiği değer bu olmalıdır. örneğin [64]vermeli 64.
  • Kullanımı evalya execveya benzer yapılarla izin verilir.

İşte bazı ek örnekler:

[list]
expression
value

[0]
0
0

[1]
1
1

[78557] 
78557
78557

[0,0]
0*0
0

[1,1]
1*1
1

[2,2]
2*2
4

[0,1]
0+1
1

[1,0]
1-0
1

[1,2]
1+2
3

[2,1]
2-1
1

[15,4,4]
15-4*4
-1

[9,8,1]
9-8-1
0

[4,2,2,4]
4-2*2+4
4

[10,9,9,12]
10-9*9+12
-59

[1,1,2,2,3,3]
1*1+2*2+3*3
14

[5,5,4,4,3,3]
5*5-4*4-3*3
0

[3,1,4,1,5,9,2,6,5,3,5,9]
3-1+4-1+5+9-2+6-5-3+5+9
29

[7637,388,389,388,387,12,0,0,34,35,35,27,27,2]
7637-388+389-388-387-12-0*0+34+35*35-27*27-2
7379

Bayt cinsinden en kısa kod kazanır. Tiebreaker daha erken bir cevaptı.


5
“İşlem sırası önemli” ile ilgili olarak, toplama ve çıkarma işlemlerinin birbirleriyle ilişkili olduğunu ve aynı önceliğe sahip olduğunu açıkça söylemek iyi olabilir.
Martin Ender

Yanıtlar:


15

Python 2,63 bayt

p=s='print-'
for x in input():s+='*+-'[cmp(x,p)]+`x`;p=x
exec s

evalİfade dizesini oluşturur ve s. Aritmetik, önceki sayı pile o andaki sayı karşılaştırılarak seçilir x. Bu sembolün üzerine geçerli numara eklenir.

İlk numara Sp3000'den akıllıca bir numara ile ele alınmıştır. İlk değeri, pherhangi bir sayıdan büyük olan ve bu nedenle -ilk sayıdan önce neden olan bir dizgeye ayarlanır . Ama, siçin başlatılır print-ile sonuç başlangıç yapan aynı zamanda print--(birlikte başlatarak 2 bayt kaydetmek için xsot sayesinde print.)


Sanırım printdizeye girip execonun yerine kullanabilirsiniz eval.
xsot

13

Pyth, 31 26 19 17 16 15 bayt

İle yapılan ifadeler *çevrimiçi olarak değerlendirilmez, ancak teorik olarak çalışırlar.

Maltysen sayesinde 2 bayt.

vsm+@"*-+"._-~k

Test takımı (değerlendirme ile).

Diğer durumlar (değerlendirme olmadan).

Tarihçe

  • 31 bayt: M+G@"*-+"->GH<GHv+sgMC,JsMQtJ\x60e
  • 26 bayt: M+G@"*-+"->GH<GHv+sgVQtQ\x60e
  • 19 bayt: vtssVm@"*-+"->Zd<~Z
  • 17 bayt: vtssVm@"*-+"._-~Z
  • 16 bayt: vssVm@"*-+"._-~k
  • 15 bayt: vsm+@"*-+"._-~k

Neden çarpma çevrimiçi çalışmıyor? İşe yaradığından emin değilseniz, cevaplamadan önce biraz daha test etmek en iyisi olabilir.
Calvin'in Hobileri,

Çünkü güvenlik önlemleri (değerlendirme sadece +ve -çevrimiçi olarak çalışır )
Leaky Nun

@HelkaHomba Henüz çevrimdışı deneme şansım olmadı, ancak çalışması gerekiyor. Çevrimiçi tercüman ile --safedeğiştirilen anahtarı kullanır . evalast.literal_eval
Dennis,

Tamam, yeterince adil.
Calvin'in Hobileri

Onaylandı, bu çevrimdışı tercüman ile çalışır.
Dennis,

12

Jöle , 18 16 15 14 bayt

I0;ð1g×⁹⁸œṗP€S

Dahili değerlendirme kullanmaz. Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Nasıl çalışır

I0;ð1g×⁹⁸œṗP€S  Main link. Input: A (list)

I               Increments; compute the deltas of all adjacent items of A.
 0;             Prepend a 0.
   ð            Begin a new, dyadic chain.
                Left argument: D (0 plus deltas). Right argument: A
    1g          Compute the GCD of 1 and each item in D.
                This yields 1 for non-negative items, -1 for negative ones.
      ×⁹        Multiply each 1 or -1 with the corresponding item of A.
                This negates every item in A that follows a - sign.
        ⁸œṗ     Partition the result by D. This splits at occurrences of non-zero
                values of D, grouping items with identical absolute value.
           P€   Take the product of each group.
             S  Sum; add the results.


1
Güzel bitti. eval
Dennis

9
Ben seninle golf oynadım. : P
Dennis,

Güzel, sıranız!
Sızdıran Rahibe

9

MATL , 12 bayt

Y'^l6MdZSh*s

Bu, @ aditsu'nun çalışma uzunluğu kodlaması hakkındaki çok güzel bir fikrini kullanır .

Çevrimiçi deneyin!

açıklama

       % Take input vector implicitly
Y'     % RLE. Produces two vectors: values and lengths
^      % Rise each value to the number of consecutive times it appears. This
       % realizes the product of consecutive equal values
l      % Push 1
6M     % Push vector of values again
d      % Consecutive differences
ZS     % Sign function. Gives 1 or -1 (no 0 in this case)
h      % Concatenate horizontally with previous 1
*      % Multiply. This gives plus or minus depending on increasing character
s      % Sum of vector. This realizes the additions or subtractions
       % Display implicitly

Haha sadece benzer bir şey yazmıştı. RLE bunun için iyi çalışıyor
Suever

Ben :-D bkz @Suever
Luis Mendo

7

CJam, 20

q~e`{~_W-g\:W@#*}%:+

Çevrimiçi deneyin

Açıklama:

q~       read and evaluate the input (array of numbers)
e`       RLE encode, obtaining [count number] pairs
{…}%     map each pair
  ~_     dump the count and number on the stack, and duplicate the number
  W-     subtract the previous number (W is initially -1 by default)
  g      get the sign of the result
  \      swap with the other copy of the number
  :W     store it in W (for next iteration)
  @#     bring the count to the top, and raise the number to that power
  *      multiply with the sign
:+       add all the results together

7

JavaScript (ES6), 54

p=>eval(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

eval virgülle ayrılmış ifadelerin bir listesini alır ve sonuncunun değerini döndürür.

Ölçek

f=p=>eval(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

t=p=>(0+p.map(v=>x+='*-+'[(p>v)+2*(p<v)]+(p=v),x=1))

function Test() {
  var a=I.value.match(/\d+/g).map(x=>+x) // convert input to a numeric array
  
  var x=f(a),y=t(a)
  O.textContent='Value '+x+'\n(no eval '+y+')'
}  

Test()
#I { width:80%}
<input value='12, 0, 7, 7, 29, 10, 2, 2, 1' id=I>
<button onclick='Test()'>Test</button>
<pre id=O></pre>


4
Bu sitede gördüğümü hatırladığım virgül operatörünün en büyük suiistimali ...
Neil



3

R, 92 bayt

Muhtemelen burada yapılabilecek bazı iyi golf oynamaları vardır.

eval(parse(t=paste(i<-scan(),c(ifelse(d<-diff(i),ifelse(d>0,"+","-"),"*"),""),collapse="")))

Ungolfed:

i = scan()                # Read list from stdin
d = diff(i)               # Calculate difference between each element of list
s = ifelse(d,             # If d!=0
             ifelse(d>0,  # And if d>1
                    "+",  # Return plus
                    "-"), # Else return minus
             "*")         # Else (i.e. d==0) return multiply.
s = c(s,"")               # Pad the list s with an empty string, so it's the same
                          # length as i
p = paste(i,s,collapse="")# Paste the elements of i and s into one long string.
eval(parse(t=p))          # Evaluate the string as a language object.



2

TI-BASIC, 146 bayt

Mobil olmadığında güzel bir şekilde biçimlendireceğim. Uyku benden kaçar, böylece anlarsın. Keyfini çıkarın.

Prompt L₁
"(→Str1
For(A,1,dim(L₁
{0,1→L₂
{0,L₁(A→L₃
LinReg(ax+b) L₁,L₃,Y₁
Equ►String(Y₁,Str2
sub(Str2,1,-1+inString(Str2,"X→Str2
If A>1
Then
L₁(A-1
2+(Ans>L₁(A))-(Ans<L₁(A
Str1+sub("+*-",Ans,1→Str1
End
Str1+Str2→Str2
End
expr(Str1

2

Javascript ES6, 64 62 karakter

a=>eval(a.map((x,i)=>x+('*+-'[x<a[++i]|(x>a[i])*2])).join``+1)

3
Bu bir işlev ve abir parametre olmamalı mı ?
edc65

Bu olduğu gibi geçersiz.
Rɪᴋᴇʀ

@ edc65, evet, olmalı. Fakat gerçekte sayıldı (61 belirtildi, ancak gerçek kod uzunluğu 59 idi), yeni bir kodu çok kötü kopyaladım (düzenleme a[i+1]...a[i+1]=> a[++i]...a[i]- 2 karakter daha kısa olmalı , ancak yanlışlıkla tüm kodun bırakılmasını değiştirdim a=>).
Qwertiy

@ EᴀsᴛᴇʀʟʏIʀᴋ, sadece yanlış bir macun. Daha fazla ayrıntı için yukarıdaki yoruma bakın ve geçmişi düzenleyin.
Qwertiy

@Qwertiy tamam harika. Güzel cevap btw ..
Rɪᴋᴇʀ

1

Java, 384 bayt

int s(int[]l){int n=l[0],m;for(int i=0;i<l.length-1;i++)if(l[i]<l[i+1])if(i<l.length-2&&l[i+1]!=l[i+2])n+=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n+=m;}else if(l[i]>l[i+1])if(i<l.length-2&&l[i+1]!=l[i+2])n-=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n-=m;}else{m=l[i];while(i<l.length-1&&l[i]==l[i+1])m*=l[i++];n+=m;}return n;}

Ungolfed çevrimiçi deneyin

int s(int[] l)
{
    int n=l[0], m;

    for(int i=0; i<l.length-1; i++)
    {
        if(l[i] < l[i+1])
        {
            if (i<l.length-2 && l[i+1]!=l[i+2])
            {
                n += l[i+1];
            }
            else
            {
                m = l[i+1];
                while(i<l.length-2 && l[i+1]==l[i+2]) m *= l[(i++)+1];
                n += m;
            }
        }
        else if(l[i] > l[i+1])
        {
            if (i<l.length-2 && l[i+1]!=l[i+2])
            {
                n -= l[i+1];
            }
            else
            {
                m = l[i+1];
                while(i<l.length-2 && l[i+1]==l[i+2]) m *= l[(i++)+1];
                n -= m;
            }
        }
        else
        {
            m = l[i];
            while(i<l.length-1 && l[i]==l[i+1]) m *= l[i++];
            n += m;
        }
    }

    return n;
}

1
Bazı hızlı çoraplar: int a=l.length, &&=> &, koyun int i=0ile aynı "çizgi" üzerine int n=l[0],m.
Sızdıran Rahibe

İçinde if(i<l.length-2&&l[i+1]!=l[i+2])n+=l[i+1];else{m=l[i+1];while(i<l.length-2&&l[i+1]==l[i+2])m*=l[(i++)+1];n+=m;bunu sadece elsebloğun içindeki içerikle değiştirebilirsiniz .
Sızdıran Rahibe

1

Javascript ES6, 79 karakter

a=>eval(`${a}`.replace(/(\d+),(?=(\d+))/g,(m,a,b)=>a+('*+-'[+a<+b|(+a>+b)*2])))

1

Perl, 49 bayt

İçin 48 bayt kodu + 1 -p

s/\d+ (?=(\d+))/$&.qw(* - +)[$&<=>$1]/ge;$_=eval

kullanım

perl -pe 's/\d+ (?=(\d+))/$&.qw(* - +)[$&<=>$1]/ge;$_=eval' <<< '12 0 7 7 29 10 2 2 1'
75

notlar

PCRE'de bir bakış açısı yakalayabileceğinizi öğrendim, ancak bu biraz sezgisel (?=(\d+))değil ((?=\d+)). Okuduktan sonra, ikincisi ile sıfır uzunlukta bir eşleşme yakalayacağınız için (bakış açısı) ve bunun yerine eskisi ile eşleşme yakalayacağınız için anlamlıdır.

8 byte tasarruf ettiğin için @ ninjalj'a teşekkürler !


@LeakyNun ben buna pek de saymak ne, ben sayısını çarpmak için mutluyum alakalı meta yazı bulamıyorum bilemezsin ama düşündüm sen ile çalışabilir beri bu -ebir ekleme ücretsiz po yapım -pe1 oldu ? Şimdilik güncelleme yapacak, ama ileriye dönük bir kaynak bulabilirsem alıntı yapabilir / bağlantı kurabilirim, harika olurdu!
Dom Hastings

3
@DomHastings 1, söylediğin sebepten dolayı + bu meta
yazıyı doğrula

@ Sp3000 teşekkürler! Hayatı boyunca bu yazıyı bulamadım! @LeakyNun Sp3000 adlı kullanıcının yorumuna göre +1 için meta yazısı
Dom Hastings

Zincirleme koşullu operatörleri kullanmak yerine, listeden seçim yapmak için uzay gemisi operatörünü kullanabilirsiniz: operatörün $&.qw(* - +)[$&<=>$1]yedek bölümünde s///.
ninjalj

@ ninjalj Elbette! şaşırtıcı, teşekkürler! -8 bununla!
Dom Hastings

1

Aslında, 30 bayt

;2@VpXdX`i-su"+*-"E`M' @o♀+εj≡

Ne yazık ki, eval ( ) komutu yalnızca TIO'daki değişmezleri değerlendirdiğinden, bu program TIO'da çalışmaz.

Açıklama:

;2@VpXdX`i-su"+*-"E`M' @o♀+εj≡
;                               duplicate input
 2@V                            overlapping sublists of length <= 2
    pXdX                        discard first and last element (length-1 sublists)
        `i-su"+*-"E`M           map: for each pair of elements
         i-su                     flatten, subtract, sign, increment (results in a 0 if b < a, 1 if b == a, and 2 if b > a)
             "+*-"E               select the correct operation
                     ' @o       put a space at the beginning of the list to pad it properly
                         ♀+     pairwise addition (since addition is not defined for strings and integers, this just zips the lists and flattens the result into a single flat list)
                           εj   join with empty string
                             ≡  eval

1

R , 120 44 bayt

r=rle(scan());c(1,sign(diff(r$v)))%*%r$v^r$l

Çevrimiçi deneyin!

Algoritma bu cevabınkine benzer , ancak sadece cevabımı kodladıktan sonra fark ettim. Kullandığım orijinal cevabımdan çok daha iyi eval(parse).

Tamamen R'nin vectorized işlemlerinden tam anlamıyla yararlanır - *işlemi ilk önce rle(x)$values ^ rle(x)$lenghtsbu vektörü kullanır ve nokta-ürünleri ile sign( diff( rle(x)$values ) )(önceden yapılmış 1) yapar.


1

05AB1E (eski) , 17 16 15 bayt

ü.S…*-+sè‚ζJJ.E

@Emigna sayesinde -2 bayt .

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Açıklama:

ü                  # Pair-wise loop over the (implicit) input-list
                   #  i.e. [12,0,7,7] → [[12,0],[0,7],[7,7]]
 .S                # Calculate the signum of the pair (-1 for a<b; 0 for a==b; 1 for a>b)
                   #  i.e. [[12,0],[0,7],[7,7]] → [1,-1,0]
   …*-+sè          # Index over "*-+" (with wrap-around)
                   #  i.e. [1,-1,0] → ['-','+','*']
         ‚ζ        # Zip the two lists together (appending the operands to the numbers)
                   #  i.e. [12,0,7,7] and ['-','+','*','+']
                   #   → [[12,'-'],[0,'+'],[7,'*'],[7,' ']]
           JJ      # Join them together
                   #  [[12,'-'],[0,'+'],[7,'*'],[7,' ']] → '12-0+7*7 '
             .E    # Evaluate as Python code
                   #  i.e. '12-0+7*7' → 61

1
Modüler indeksleme nedeniyle , dizenin sonuna >hareket ettirerek kaldırabilirsiniz +.
Emigna

@Emigna Bunu nasıl özlediğimden emin değilim .. Teşekkürler!
Kevin Cruijssen

1
Başka bir bayt'ı kaldırarak Ćve kaydedebilirsiniz ¨, ‚ζyerine kullanırsanızø
Emigna

@Emigna Oh, şimdi bu akıllı! Teşekkürler. Çevreleyen biraz garip bir iş olduğunu biliyordum, ama nasıl düzelteceğini bilmiyordum. ‚ζmükemmel bir alternatif çözümdür, çünkü alan değerlendirmede yok sayılır. Tekrar teşekkürler. :)
Kevin Cruijssen

0

PHP, 103 bayt

Güzel bir meydan okuma. Bu beklenenden daha uzun sürdü. PHP'de array_mapanonim işlevler hala pahalı olduğundan, kullanım veya benzeri bayt sayısını artırmayacağını düşünüyorum .

foreach(fgetcsv(STDIN)as$v)(0<=$p?$o.=$p.('*-+'[($p>$v)+2*($p<$v)]):_)&&$p=$v;echo eval("return$o$v;");

Komut satırından çalıştırıldığında, virgülle ayrılmış bir liste istenir, örneğin:

php array_to_math.php
12, 0, 7, 7, 29, 10, 2, 2, 1

0

PowerShell v2 +, 62 bayt

-join($args|%{"$o"+'*+-'[($o-lt$_)+2*($o-gt$_)];$o=$_})+$o|iex

Girdiyi, otomatik diziye dönüştürülen, boşlukla ayrılmış komut satırı argümanları olarak alır $args. $oÖnceki girişimizin ne olduğunu hatırlamak için her bir yinelemede yardımcı değişken kullanarak her bir öğe boyunca yineliyoruz . Biz (önceki giriş küçükse örneğin, dolaylı-dönüştürülmüş Boole değerlere matematik gerçekleştirerek yapılır, uygun operatörü, çekme yönündeki bir dizine-string kullanmak []için değerlendirir 1+2*0böylece '*+-'[1]anlamına gelir +seçilir).

Birleştirilmiş dizeler boru hattında bırakılır. Biz (örneğin birlikte bu snippet'lar toplamak 3-, 1+, 4-bir ile, vs.) -joinoperasyonu, CONCATENATE (örtük dizeye dönüştürülür) son sayısına ve boru bunun için iex(için takma Invoke-Expressionve benzeri eval).


Endişe verici, eğer arayan kişi zaten $ oa değeri verdiyse ($ o = 999 diyelim), o zaman bu girişteki ifade doğru değeri hesaplamayacaktır. Bu çözüme $ o başlatılması eklenmelidir.
Bevo

@Bevo Bu, bir işlev veya etkileşimli kabuk aracılığıyla değil, komut satırı üzerinden yürütülen tam bir komut dosyası olarak tasarlanmıştır. Gönderimlerimin büyük çoğunluğu böyledir, çünkü böyle bir senaryoda endişelenecek önceden tanımlanmış bir değişken yoktur ve bu nedenle kod biraz daha kısa olabilir.
AdmBorkBork,


0

Japt -x , 21 19 bayt

änJ f mÎí*Uò¦ ®ÎpZÊ

Dene


açıklama

                        :Implicit input of array U
  J                     :Prepend -1
än                      :Get deltas
    f                   :Filter (remove 0s)
      m                 :Map
       Î                : Signs
        í               :Interleave
          U             :  Original input
           ò            :  Partition on
            ¦           :   Inequality
              ®         :  Map each sub-array Z
               Î        :    Get first element
                p       :    Raise to the power of
                 ZÊ     :     Length of Z
         *              :Reduce each pair of elements by multiplcation
                        :Implicitly reduce by addition and output
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.