Ăn kiên trì

Oct 16 2020

Giới thiệu

Tìm kết quả của việc ăn thịt đồng loại.

Tại sao 6 sợ 7? Trở thành 7 89.

Chương trình của bạn sẽ phải tìm kết quả của việc áp dụng 8thao tác (được định nghĩa bên dưới) trên một số, lặp đi lặp lại.

Liên quan , Hộp cát

Thử thách

Đầu vào của bạn sẽ là một số nguyên dương duy nhất, n.

Bạn cần tìm từng 8số nguyên và thay thế nó cho +hoặc -dựa trên các điều kiện sau.

  • loại bỏ tất cả 8s ở đầu hoặc cuối của chuỗi.
  • Nếu có nhiều 8s, sau đó thu gọn chúng thành một 8.
  • \$a\$và \$b\$là các phần ở bên trái và bên phải 8tương ứng. Vì 8là một toán tử, các số được phân định bằng 8.
  • Nếu \$ a ≥ b,\$ 8trở thành +.
  • khác, nó trở thành -.

Sau đó, đánh giá biểu thức từ trái sang phải và lấy giá trị tuyệt đối.

Nếu kết quả có bất kỳ 8s trong đó, hãy lặp lại các bước trên một lần nữa cho đến khi không có.

Ví dụ, 12384568789trở thành:

123 456 7 9
123 < 456: 123 - 456 7 9
456 ≥ 7  : 123 - 456 + 7 9
7 < 9    : 123 - 456 + 7 - 9 = -335
= abs(-335)
= 335

Do đó, 335 là câu trả lời cuối cùng.

Ví dụ đầu vào và đầu ra

789 → 2
180 → 1
42312348 → 4231234
2389687 → 66
12384568789 → 335
13749547874394873104972349 → 7309154
808 → 0
7800482 → 13
14458883442 → 1997
88888 → indeterminate
388182 → 2
08182 → 3

Dưới đây là các tủ thử nghiệm dưới dạng một mảng:

[789,180,42312348,2389687,12384568789,13749547874394873104972349,808,7800482,14458883442,88888]

Tiêu chí chấm điểm

Đây là mã-gôn . Câu trả lời ngắn nhất trong mỗi ngôn ngữ sẽ chiến thắng.

Trả lời

8 KevinCruijssen Oct 16 2020 at 17:29

05AB1E , 18 14 byte

Δ8¡þDü@1š·<*OÄ

Hãy 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:

Δ               # Loop until it no longer changes:
 8¡             #  Split the integer on 8s
                #  (which will use the implicit input-integer in the first iteration)
   þ            #  Remove all empty strings by only leaving digits
    D           #  Duplicate this list
     ü          #  For each overlapping pair [a,b]:
      @         #   Check if a>=b (1 if truthy; 0 if falsey)
       1š       #  Prepend a 1 to this list
         ·      #  Double each value
          <     #  Decrease each by 1 (0 has become -1; 1 is still 1)
           *    #  Multiply the values at the same positions in the two lists
            O   #  Sum the list
             Ä  #  And take the absolute value of this sum
                # (after which the result is output implicitly)
7 UnrelatedString Oct 16 2020 at 13:57

Thạch , 20 18 byte

IŻṠo-×
ṣ8LƇḌÇSAµÐL

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

Đã đi qua 5 hoặc 6 cách tiếp cận khác trước khi eval hóa ra là cách duy nhất tôi có thể làm việc ... và sau đó tôi đã thử một vòng quay khác trên cách tiếp cận thứ hai của mình và nó ngắn hơn 2 byte.

Phiên bản cũ: ṣ8LƇḌ<Ɲị⁾_+ż@ƲFVAµÐL

IŻṠo-×         Monadic helper link:
  Ṡ            signs of
I              deltas
 Ż             with prepended 0,
   o-          replace all 0s with -1s,
     ×         pairwise multiply with argument.

ṣ8LƇḌÇSAµÐL    Main link:
ṣ8             split (implicitly converted digit list) on 8s,
  LƇ           remove empty slices,
    Ḍ          convert digit lists from decimal,
     Ç         apply helper link,
      S        sum,
       A       abs.
        µÐL    Loop that whole thing until it doesn't change.
7 Arnauld Oct 16 2020 at 14:09

JavaScript (ES6), 76 byte

f=n=>n.replace(p=/[^8]+/g,x=>t-=p<(p=+x)?x:-x,t=0)&&n-(t=t<0?-t:t)?f(t+''):t

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

Đã nhận xét

f = n =>               // f is a recursive function taking n as a string
  n.replace(           // we look for ...
    p = /[^8]+/g,      // ... all groups of consecutive non-eight digits
    x =>               // for each group x:
      t -=             //   update t:
        p < (p = +x) ? //     if the previous value is less than x:
          x            //       subtract x from t
        :              //     else:
          -x,          //       add x to t
    t = 0              //   start with t = 0
  ) &&                 // end of replace()
  n - (                // if n is not equal to t,
    t = t < 0 ? -t : t // where t is first updated to its absolute value:
  ) ?                  //
    f(t + '')          //   do a recursive call with t (coerced back to a string)
  :                    // else:
    t                  //   success: return t
5 DominicvanEssen Oct 17 2020 at 16:32

Husk , 27 26 25 byte

Chỉnh sửa: -1 byte bằng cách sử dụng bộ Stổ hợp để tái chế đối số hàm và di chuyển hàm trợ giúp trong dòng, sau đó -1 byte nữa bởi một chút sắp xếp lại để có thể sử dụng bộ otổ hợp thay vì()

ω(aΣSz*o:1Ẋȯ`^_1¬<mdfIx8d

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

Một cách tiếp cận hơi khác đối với câu trả lời Husk của chuỗi không liên quan , cũng là 27 byte .

Tôi đã tạm dừng việc đăng bài này một chút, để cung cấp cho bất kỳ Husker mới nào một phương tiện sạch để từ đó thử thách thức này ... nhưng bây giờ Husketition đã mở ...

Làm sao? *

mdfIx8d                 # helper function: splits input on 8s
      d                 # get digits of input
    x8                  # split on 8  
  f                     # remove elements that are falsy for
   I                    # the identity function (so, remove empty elements)
m                       # map over each element of the list 
 d                      # combining digits as decimal number
 
ωλaΣz*₁¹m`^_1ΘẊo¬<₁     # main program
ω                       # repeatedly apply function until results are constant
 λ                      # lambda function taking one argument:
  a                     # get the absolute value of
   Σ                    # the sum of all elements of
    z*                  # element-wise multiplication of
      ₁¹                # (1) helper function applied to input
                        #     (so: the input split on 8s)
        m               # (2) map this function to all elements of
                  ₁     #     helper function applied to input
             Θ          #     (with 0 prepended at the start)                 
         `^_1           #     minus one to the power of
              Ẋ         #     the results for each pair of elements
               o        #     combine 2 functions
                ¬       #     NOT
                 <      #     second is greater than first    
4 DominicvanEssen Oct 16 2020 at 16:45

R , 89 122 byte

Chỉnh sửa: +33 byte để chuyển đổi sang hàm đệ quy khi tôi nhận ra rằng nó nên lặp lại 8thao tác trên đầu ra của chính nó cho đến khi không còn 8s nữa . Doh!

f=function(s)`if`(grepl(8,a<-abs(sum(c(1,-sign(diff(n<-sapply((n=el(strsplit(s,8)))[n>-1],as.double))))*n))),f(c(a,'')),a)

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

Chấp nhận đối số ndưới dạng một chuỗi. Lỗi đối với ns không chứa 8 chữ số / ký tự.

4 Lyxal Oct 16 2020 at 13:18

Python 3 , 158 148 145 138 byte

x=input()
while'8'in x:
 y=[int(f)for f in x.split('8')if f];x=str(sum([-1,1][y[i-1]<y[i]]*y[i]for i in range(len(y))))
print(abs(int(x)))

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

-10 byte cảm ơn @ pavi2410 và tôi không phải là một tên ngốc và vô tình để lại một khoảng trống từ gợi ý chơi gôn

và -3 người khác cảm ơn @ pavi2410

và -7 khác nhờ @ pavi2410

4 Noodle9 Oct 16 2020 at 21:54

C (gcc) , 149 \$\cdots\$ 139 137 byte

Đã tiết kiệm được 2 byte nhờ cat trần !!!
Đã tiết kiệm được 8 byte nhờ AZTECCO !!!

R;t=10;m;s;p;c;f(n){R=n;for(s=p=0;n;){for(m=1,c=0;n&&n%t-8;n/=t,m*=t)c+=n%t*m;s+=c>p?p:-p;for(p=c;n%t==8;)n/=t;}p=abs(s+c);R=p-R?f(p):p;}

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

Giải thích (trước một số cuộc chơi gôn)

t=10;                                 // golf by storing 10 in t
g(n){                                 // helper function takes int n  
     for(     ;n;){                   // loops until n is zero  
         s=p=0                        // init sum s and previous p to 0  
       for(                           // inner loop calculates next rh value  
           m=1,                       // init multiplier m to 1  
               c=0;                   // and current c to 0   
                   n&&                // loop until n is 0   
                      n%t-8;          // or most rh digit is 8     
                            n/=t,     // knock most rh digit off n      
                               m*=t)  // and bump m by 10 each loop  
         c+=n%t*m;                    // add next digit to current 
                                      // building up number after  
                                      // most right-hand 8  
      s+=c>p?p:-p;                    // after that's done update sum s  
      for(                            // loop to strip off all rh 8's  
          p=c;                        // also make previous = current  
              n%t==8;)                // loop until most rh digit isn't an 8  
                      n/=t;           // knock most rh 8 off n   
        }                             //   
 p=abs(s+c);                          // return abs value of sum with   
                                      // positive most lh value  
}                                     //  
f(n){                                 // recursive main function  
     x=g(n);                          // calc first iteration
            x=x-g(x)?                 // is it different to next iteration?  
                     f(x):            // if so iterate  
                          x;          // else return value   
}                                     //  
4 Xcali Oct 18 2020 at 06:24

Perl 5 -p , 59 byte

y/8/ /;s/\d+/$&<$'?"$&-":"$&+"/ge;$_=abs eval$_.0;/8/&&redo

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

4 xash Oct 18 2020 at 07:32

J , 53 byte

|@('8'+/@(*_1x^0,2</\])@(,(*@#;._1#".;._1)~[=,)":)^:_

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

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

  • f^:_: cho đến khi kết quả không thay đổi, thực hiện f.
  • '8'…(,g[=,)":: chuyển đổi đầu vào thành một chuỗi, thêm ,ký tự trước 8và thực thi gvới điều này làm đối số bên trái và một mặt nạ bit của các 8ký tự làm đối số bên phải.
  • (…".;._1)~: chia chuỗi thành các nhóm u;._1, bắt đầu bằng 1 trong mặt nạ bit và chuyển đổi chúng trở lại thành số ".(không bao gồm 8).
  • *@#;._1#: Vì chúng ta có thể có các nhóm rỗng ( 888), hãy #chỉ những, có chiều dài của #signum *là 1. (Có thể có một cách tiếp cận đẹp hơn.)
  • 2</\]: so sánh <mỗi nhóm với nhóm sau, tạo ra một bit-mask.
  • *_1x^0,: thêm 0 vào mặt nạ bit và tính toán x*(-1)^ycho mỗi nhóm xbằng ykết quả của phép so sánh. Vì vậy, chúng tôi nhận được 3 1 2 -> 3 1 _2.
  • |@…+/: tính tổng +/kết quả và lấy giá trị tuyệt đối |.
3 user Oct 16 2020 at 22:53

Scala , 94 90 byte

i=>"[^8]+".r.findAllIn(""+i).map(_.toInt).scanRight(0){(a,b)=>if(a<b.abs)a else-a}.sum.abs

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

-4 byte bằng cách không sử dụng splitphương thức bị nguyền rủa của Java .

i=>                           //The input
  "[^8]+".r                   //Regex for operands
  .findAllIn(""+i)            //Get all separate numbers in the input
  .map(_.toInt)               //Turn them into integers
  .scanRight(0){(a,b)=>       //Starting at the right,
    if(a<b.abs)a else-a}      //Replace a with -a if a >= b.abs (this is different from the challenge, but it works because we call abs again later)
  .sum                        //Sum them up
  .abs                        //Take the absolute value
3 UnrelatedString Oct 17 2020 at 07:21

Husk , 27 byte

ω(aΣSz*(Ẋȯ`^_1±>Ṡ:←)mdfIx8d

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

Đây hoàn toàn không phải là câu trả lời Husk đầu tiên của tôi, nhưng đó là một bản dịch trực tiếp khá vụng về của một trong những câu trả lời Jelly đã cố gắng của tôi, vì vậy nó ít nhất có thể là một điểm khởi đầu có thể sử dụng được để ai đó có thể tham gia và kiếm tiền thưởng.

ω(                             Iterate until periodic:
  a                            absolute value of
   Σ                           sum of
     z*                        zipwith multiplication on:
                          d    decimal digits
                        x8     split on 8s
                      fI       with empty slices removed
                    md         and converted back from decimal,
    S                          and the result of that
       (        Ṡ:←)           with its first element duplicated
        Ẋ                      and with neighboring pairs mapped to
          `^_1                 -1 to the power of
         ȯ    ±>               if the first is less than the second.
3 PetrFiedler Oct 17 2020 at 09:39

Bash , 177 byte

A=($(sed s/8/\ /g<<<$1));B=;while [ ${#A[@]} -ge 2 ];do [ ${A[0]} -ge ${A[1]} ]&&C=+||C=-;B=$B${A[0]}$C;A=(${A[@]:1});done;R=$(bc<<<$B$A|tr -d -);grep -cq 8 <<<$R&&f $R||echo $R

Nó phải được lưu trữ dưới dạng hàm fhoặc trong tệp ftrong thư mục làm việc hiện tại.

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

3 ZsoltSzilagy Oct 18 2020 at 04:35

PHP, 290 byte

(Đoán rằng bạn không nên chơi gôn trong php. :))

<?php $n=$_SERVER["argv"][1];while(false!==strpos($n,'8')){$n=abs(array_reduce(str_split(preg_replace('|8+|','8',trim($n,'8')).'8'),function($c,$i){if($i!=8){$c[1]*=10;$c[1]+=$i;}else{$c[2]+=$c[1]*((!isset($c[0])||$c[0]>=$c[1])?1:-1);$c[0]=$c[1];$c[1]=0;}return$c;},[null,0,0])[2]);}echo$n;

Thử trực tuyến

Không thích:

<?php

$n = $_SERVER["argv"][1]; $f=function($c, $i){
    if($i!=8) { $c[1]*=10;
        $c[1]+=$i;
    } else {
        $c[2] += $c[1] * ( (!isset($c[0]) || $c[0]>=$c[1])?1:-1); $c[0]=$c[1]; $c[1]=0;
    }
    return $c; }; while(false!==strpos($n,'8')) {
    $n = trim($n, '8');
    $n = preg_replace('|8+|', '8', $n);
    $a = str_split($n.'8');
    $n = abs(array_reduce($a, $f, [null, 0, 0])[2]); } echo $n;

Giải trình:

Tôi sử dụng array_reduce để xem qua từng chữ số và sử dụng một mảng làm carry để có 3 điểm dữ liệu được thực hiện: các biến $a, $ban nhạc $sum, though they are unnamed as the elements of $c.

Nếu chữ số hiện tại không phải là 8, tôi "thêm" nó vào "$b", otherwise I first compare $b tới $a, add/subtract $b từ $sum, and move the content of $b đến $ a.

2 GalenIvanov Oct 16 2020 at 17:47

Đỏ , 142 byte

func[n][while[find to""n"8"][b: to[]load form split to""n"8"forall b[if b/2[b/1:
reduce[b/1 pick[- +]b/1 < b/2]]]n: absolute do form b]to 1 n]

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

2 2014MELO03 Oct 16 2020 at 22:53

GolfScript , 32 byte

.,{8`%(~:x\{~.x\:x<2*(*-}/abs`}*

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

Mỗi khi thuật toán được thực thi, số sẽ được giữ nguyên hoặc ngắn hơn ít nhất 1 chữ số. Điều này có nghĩa là chúng ta có thể thực thi thuật toán một lần cho mỗi byte thay vì thử nghiệm nếu nó có 8.

.,                                 # Get the number of bytes in the input
  {                           }*   # Execute this block that many times
   8`%                             # Split the string around the 8s and remove the empty strings
                                   # This simultaneously executes the first 3 steps
      (~                           # Get the first number
        :x                         # Store it in the variable x
          \{~           }/         # For each number left in the array
             .x                    # Copy it and push x
               \:x                 # Store the current number in x
                  <                # Compare the two numbers
                   2*(             # 1 if previous<current and -1 if previous>=curret
                      *-           # Multiply and subtract
                          abs`     # Parse the absolute value to a string
2 AZTECCO Oct 17 2020 at 21:26

Japt , 37 byte

@=q8 f;=äÈn ¨Y?Y:-Y}Ug)x a s ,Uø8}f U

Thử nó

  • lấy đầu vào là một chuỗi, có thể dễ dàng sửa đổi để lấy đầu vào là một số nhưng sẽ không hoạt động với các số lớn

''

@=q8 f;=äÈn ¨Y?Y:-Y}Ug)x a s ,Uø8}f U
@....}f    - return first number which return false when passed through @...
=q8 f;     - input splitted on 8 and empties removed
=äÈ...}Ug) - pass each consecutive values through È , but prepend first value before so that they are >=
n ¨Y?Y:-Y  - 1st to number compared to 2nd: return 2nd (negated eventually)
x a s      - reduce->abs->to string

The above is assigned to U while the funxtion returns..
Uø8        - contains 8? => repeat
Finally we return U

''

2 GalenIvanov Oct 17 2020 at 03:26

K (oK) , 60 43 38 byte

-22 byte nhờ Traws

{a|-a:+/{x*1-2*>':x}.:'(~^.)#"8"\$:x}/

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

1 Neil Oct 16 2020 at 16:38

Retina 0,8,2 , 68 byte

{`8+
-
^-|-$ \d+ $*
(?=-(1*))(?<=\1)-
+
O`\D1*
\+

1>`-

(1+)-\1

1

Hãy thử nó trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm nhỏ hơn (Retina phải thực hiện phép trừ trong một đơn vị, quá chậm đối với các trường hợp lớn hơn). Giải trình:

{`

Lặp lại cho đến khi không còn 8s.

8+
-

Chuyển mỗi lần chạy 8s thành a -.

^-|-$

Xóa -các s đầu và cuối .

\d+
$*

Chuyển các số còn lại thành đơn phân.

(?=-(1*))(?<=\1)-
+

Thay mỗi cái -bằng một +trừ khi số sau lớn hơn.

O`\D1*

Sắp xếp các số được thêm vào đầu và các số bị trừ đến cuối.

\+

Cộng tất cả các số được cộng lại với nhau.

1>`-

Cộng tất cả các số bị trừ với nhau.

(1+)-\1
   

Lấy giá trị tuyệt đối của chênh lệch.

1

Chuyển nó thành số thập phân.