Biến một mảng thành một vấn đề toán học


35

Đưa ra một danh sách các số nguyên không âm, xem xét viết lại nó như là một vấn đề số học trong đó:

  • Dấu cộng ( +) được chèn giữa các cặp số tăng dần từ trái sang phải (còn gọi là từ đầu danh sách đến cuối).
  • Dấu trừ ( -) được chèn giữa các cặp số giảm dần từ trái sang phải.
  • Dấu nhân ( *) được chèn giữa các cặp số bằng nhau.

Nói một cách khác: bất kỳ danh sách con nào a,btrở thành a+bif a<b, a-bif a>ba*bif a==b.

Ví dụ, danh sách

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

sẽ trở thành biểu thức

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

đánh giá 75 .

Viết chương trình hoặc hàm lấy trong danh sách đó và đánh giá nó, in hoặc trả về kết quả.

  • Thứ tự các vấn đề hoạt động. Phép nhân nên được thực hiện trước khi cộng hoặc trừ.
  • Nếu danh sách đầu vào có một số, đó sẽ là những gì nó đánh giá. vd [64]nên cho 64.
  • Sử dụng evalhoặc exechoặc các cấu trúc tương tự được cho phép.

Dưới đây là một số ví dụ bổ sung:

[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

Mã ngắn nhất tính bằng byte thắng. Tiebreaker là câu trả lời trước đó.


5
Về "thứ tự các vấn đề hoạt động", có thể tốt để nói rõ rằng phép cộng và phép trừ là liên kết trái và có cùng mức ưu tiên.
Martin Ender

Câu trả lời:


15

Python 2, 63 byte

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

Xây dựng và evals chuỗi biểu thức. Biểu tượng số học được chọn bằng cách so sánh số trước với số phiện tại x. Biểu tượng được nối thêm theo số hiện tại.

Số đầu tiên được xử lý với một mẹo thông minh từ Sp3000. Giá trị ban đầu của pđược đặt thành một chuỗi, lớn hơn bất kỳ số nào và do đó gây ra một -trước số đầu tiên. Nhưng, sđược khởi tạo print-cùng lúc khiến kết quả bắt đầu bằng print--(nhờ xsot để lưu 2 byte bằng cách khởi tạo với print.)


Tôi nghĩ rằng bạn có thể di chuyển printvào chuỗi và sử dụng execthay vì eval.
xsot

13

Pyth, 31 26 19 17 16 15 byte

Biểu thức *không đánh giá trực tuyến, nhưng về mặt lý thuyết chúng sẽ hoạt động.

2 byte nhờ Maltysen.

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

Bộ thử nghiệm (có đánh giá).

Các trường hợp khác (không có đánh giá).

Lịch sử

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

Tại sao phép nhân không hoạt động trực tuyến? Nếu bạn không chắc chắn nó hoạt động, tốt nhất nên kiểm tra thêm một chút trước khi trả lời.
Sở thích của Calvin

Bởi vì công cụ bảo mật (đánh giá chỉ hoạt động cho +-trực tuyến)
Leaky Nun

@HelkaHomba Tôi chưa có cơ hội dùng thử ngoại tuyến, nhưng nó sẽ hoạt động. Trình thông dịch trực tuyến sử dụng công --safetắc, thay thế evalbằng ast.literal_eval.
Dennis

Được rồi.
Sở thích của Calvin

Xác nhận, điều này hoạt động với trình thông dịch ngoại tuyến.
Dennis

12

Thạch , 18 16 15 14 byte

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

Sử dụng không có eval tích hợp. Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Làm thế nào nó hoạt động

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
Hoàn thành tốt Tôi nên thêm Python evalnhư một nguyên tử ...
Dennis

9
Tôi ra ngoài chơi gôn với bạn. : P
Dennis

Hoàn thành tốt, đến lượt bạn!
Nữ tu bị rò rỉ

9

MATL , 12 byte

Y'^l6MdZSh*s

Điều này sử dụng ý tưởng rất hay về mã hóa độ dài chạy của @ aditsu .

Hãy thử trực tuyến!

Giải trình

       % 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 vừa mới viết một cái gì đó tương tự. RLE hoạt động tốt cho việc này
Suever

@Suever Tôi thấy :-D
Luis Mendo

7

CJam, 20

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

Dùng thử trực tuyến

Giải trình:

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 nhận được một danh sách các biểu thức được phân tách bằng dấu phẩy và trả về giá trị của biểu thức cuối cùng.

Kiểm tra

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
Đó là sự lạm dụng tồi tệ nhất của toán tử dấu phẩy mà tôi có thể nhớ đã thấy trên trang web này ...
Neil


4

Pyth - 23 22 20 byte

Như với Kenny, phép nhân không hoạt động trực tuyến.

vs.i+\+@L"*+-"._M-Vt

Test Suite mà không làm eval .


Kevin là ai?
Nữ tu bị rò rỉ

@LeakyNun Tôi đã quên tên của bạn sau một thời gian> _>
Maltysen

@Maltysen Haha, bạn đang nghĩ về kevin-not-kenny Lau
DJMcMayhem

Xin lỗi, tôi đã ăn, vì vậy tôi không thể đánh golf giải pháp của mình. Lượt của bạn.
Nữ tu bị rò rỉ

@LeakyNun gần như ở đó
Maltysen

3

R, 92 byte

Có khả năng vẫn còn một số golf tốt có thể được thực hiện ở đây.

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

Ung dung:

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.

Tôi đã cố gắng tiết kiệm chỉ một byte bằng cách sử dụng phương pháp lập chỉ mục
JayCe


2

TI-BASIC, 146 byte

Tôi sẽ định dạng độc đáo khi không có trên điện thoại di động. Giấc ngủ thoát khỏi tôi, vì vậy bạn có được điều này. Thưởng thức.

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 ký tự

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

3
Đây không phải là một chức năng và amột tham số?
edc65

Điều này là không hợp lệ.
Rɪᴋᴇʀ

@ edc65, vâng, nó nên. Nhưng trên thực tế, nó đã được tính (61 chỉ định, nhưng độ dài mã thực là 59), tôi chỉ sao chép sai một mã mới (chỉnh sửa nên a[i+1]...a[i+1]=> a[++i]...a[i]- 2 ký tự ngắn hơn, nhưng tôi đã thay thế nhầm toàn bộ mã giảm a=>).
Qwertiy

@ EᴀsᴛᴇʀʟʏIʀᴋ, đó chỉ là một dán sai. Xem bình luận ở trên và chỉnh sửa lịch sử để biết thêm chi tiết.
Qwertiy

@Qwertiy ổn. Câu trả lời hay btw ..
Rɪᴋᴇʀ

1

Java, 384 byte

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

Ung dung thử trực tuyến

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
Một số golf nhanh : int a=l.length, &&=> &, đặt int i=0cùng một "dòng" như int n=l[0],m.
Leaky Nun

Trong 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;, bạn chỉ có thể thay thế điều này bằng nội dung bên trong elsekhối.
Nữ tu bị rò rỉ

1

Javascript ES6, 79 ký tự

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

1

Perl, 49 byte

Mã 48 byte + 1 cho -p

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

Sử dụng

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

Ghi chú

Tôi đã học được ở đây rằng bạn có thể chụp một cái nhìn trong PCRE, mặc dù nó hơi không trực quan ( (?=(\d+))thay vì ((?=\d+))). Nó thực sự có ý nghĩa sau khi đọc mặc dù bạn sẽ chụp một trận đấu có độ dài bằng không (cái nhìn) với cái sau, và thay vào đó là chụp trận đấu với cái trước).

Cảm ơn @ninjalj vì đã tiết kiệm 8 byte!


@LeakyNun Tôi không bao giờ biết chính xác những gì cần tính cho điều đó, tôi không thể tìm thấy bài đăng meta có liên quan, tôi rất vui khi được tính số đếm, nhưng tôi nghĩ rằng vì bạn có thể chạy -emiễn phí, thêm vào pđó -pelà +1 ? Sẽ cập nhật ngay bây giờ, nhưng nếu bạn có thể tìm thấy một nguồn tôi có thể trích dẫn / liên kết để tiếp tục, điều đó thật tuyệt vời!
Dom Hastings

3
@DomHastings 1 là chính xác, theo lý do bạn nói + bài đăng meta này
Sp3000

Cảm ơn @ Sp3000! Tôi không thể tìm thấy bài viết đó cho cuộc sống của tôi! @LeakyNun meta bài đăng cho +1 theo nhận xét từ Sp3000
Dom Hastings

Thay vì sử dụng các toán tử có điều kiện, bạn có thể sử dụng toán tử tàu vũ trụ để chọn từ danh sách: $&.qw(* - +)[$&<=>$1]trong phần thay thế của s///toán tử.
ninjalj

@ninjalj Tất nhiên rồi! tuyệt vời, cảm ơn! -8 với điều đó!
Dom Hastings

1

Trên thực tế, 30 byte

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

Thật không may, vì eval ( ) chỉ đánh giá các chữ trên TIO, chương trình này không hoạt động trên TIO.

Giải trình:

;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 byte

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

Hãy thử trực tuyến!

Thuật toán tương tự như câu trả lời này , nhưng tôi chỉ nhận ra nó sau khi mã hóa câu trả lời của mình. Tốt hơn nhiều so với câu trả lời ban đầu của tôi đang sử dụng eval(parse).

Tận dụng triệt để các *hoạt động được vector hóa của R - thực hiện thao tác đầu tiên bằng cách sử dụng rle(x)$values ^ rle(x)$lenghtsvà chấm các sản phẩm này theo vectơ này sign( diff( rle(x)$values ) )(có trước 1).


1

05AB1E (di sản) , 17 16 15 byte

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

-2 byte nhờ @Emigna .

Dùng thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

ü                  # 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
Do lập chỉ mục mô-đun, bạn có thể loại bỏ >bằng cách di chuyển +đến cuối chuỗi.
Emigna

@Emigna Không chắc tôi đã bỏ lỡ điều đó như thế nào .. Cảm ơn!
Kevin Cruijssen

1
Bạn có thể lưu một byte khác bằng cách xóa ƨ, nếu bạn sử dụng ‚ζthay vìø
Emigna

@Emigna ơi, bây giờ thì thông minh! Cảm ơn. Tôi biết bao vây là một chút công việc kỳ lạ, nhưng không biết cách khắc phục. ‚ζlà một công việc thay thế hoàn hảo, vì không gian bị bỏ qua trong eval. Cảm ơn một lần nữa. :)
Kevin Cruijssen

0

PHP, 103 byte

Thử thách gọn gàng. Điều này đã lâu hơn dự kiến. Tôi nghĩ rằng việc sử dụng array_maphoặc tương tự sẽ không cải thiện số byte, vì các hàm ẩn danh vẫn còn đắt đỏ trong PHP.

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

Chạy từ dòng lệnh, sẽ nhắc cho một danh sách được phân tách bằng dấu phẩy, như:

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

0

PowerShell v2 +, 62 byte

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

Đưa đầu vào dưới dạng đối số dòng lệnh được phân tách bằng dấu cách, được chuyển đổi thành mảng tự động $args. Chúng tôi lặp qua từng phần tử, sử dụng biến của trình trợ giúp $omỗi lần lặp để ghi nhớ mục nhập trước đó của chúng tôi là gì. Chúng tôi sử dụng một chỉ mục dây để kéo ra khỏi các nhà điều hành thích hợp, thực hiện bằng cách thực hiện toán trên các giá trị Boolean ngầm-chuyển đổi (ví dụ, nếu mục trước là nhỏ hơn, []đánh giá lại để 1+2*0như vậy '*+-'[1]có nghĩa là các+ được chọn).

Các chuỗi nối được để lại trên đường ống. Chúng tôi thu thập tất cả những đoạn với nhau (ví dụ như, 3-, 1+, 4-, vv) với một -joinhoạt động, tiếp nhau trên con số cuối cùng (mặc nhiên chuyển thành chuỗi), và ống nó iex(bí danh cho Invoke-Expressionvà tương tự như eval).


Một mối quan tâm là nếu người gọi đã đưa ra giá trị $ oa (giả sử $ o = 999) thì biểu thức trong mục này sẽ không tính giá trị đúng. Việc khởi tạo $ o cần được thêm vào giải pháp này.
Bevo

@Bevo Đây được dự định là một tập lệnh đầy đủ, được thực thi thông qua dòng lệnh và không phải là một chức năng hoặc thông qua trình vỏ tương tác. Phần lớn các bài nộp của tôi là như vậy, vì trong kịch bản như vậy, không có biến nào được xác định trước để lo lắng và do đó mã có thể ngắn hơn một chút.
admBorkBork

0

Japt , 25 byte

Muốn cắt ngắn hơn, nhưng tôi không thể làm cho một phiên bản eval-less hoạt động.

S+Uä!- ®"*+-"gZÎì)íU
OxU

Hãy thử trực tuyến!


Có nó xuống đến 22 byte nhưng vẫn nghĩ rằng nó có thể được cải thiện.
Xù xì

0

Japt -x , 21 19 byte

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

Thử nó


Giải trình

                        :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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.