Manger de la persévérance

Oct 16 2020

Intro

Trouvez le résultat du cannibalisme des nombres.

Pourquoi 6 avait-il peur de 7? Becase 7 89.

Votre programme devra trouver le résultat de l'application de l' 8opération (définie ci-dessous) sur un nombre, à plusieurs reprises.

Connexes , Sandbox

Défi

Votre entrée sera un seul entier positif, n.

Vous devez trouver chacun 8dans l'entier et le remplacer par +ou en -fonction des conditions suivantes.

  • supprime tous les 8s au début ou à la fin de la chaîne.
  • S'il y a plusieurs 8s, réduisez-les en un seul 8.
  • \$a\$et \$b\$sont les morceaux à gauche et à droite de 8respectivement. Puisqu'il 8s'agit d'un opérateur, les nombres sont délimités par 8.
  • Si \$ a ≥ b,\$ 8devient +.
  • sinon, ça devient -.

Évaluez ensuite l'expression de gauche à droite et prenez la valeur absolue.

Si le résultat contient des 8s, répétez les étapes ci-dessus jusqu'à ce qu'il n'y en ait pas.

Par exemple, 12384568789devient:

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

Par conséquent, 335 est la réponse finale.

Exemple d'entrée et de sortie

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

Voici les cas de test sous forme de tableau:

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

Critères de notation

C'est du code-golf . La réponse la plus courte dans chaque langue l'emporte.

Réponses

8 KevinCruijssen Oct 16 2020 at 17:29

05AB1E , 18 14 octets

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

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

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

Gelée , 20 18 octets

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

Essayez-le en ligne!

Je suis passé par 5 ou 6 autres approches avant qu'éval ne se révèle être le seul que je puisse mettre au travail ... puis j'ai essayé une variante différente de ma deuxième approche et c'est 2 octets plus court.

Ancienne version: ṣ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 octets

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

Essayez-le en ligne!

Commenté

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 octets

Edit: -1 octet en utilisant le Scombinateur pour recycler l'argument de la fonction, et déplacer la fonction d'assistance en ligne, puis -1 octet de plus par un peu de réarrangement pour pouvoir utiliser le ocombinateur au lieu de()

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

Essayez-le en ligne!

Une approche légèrement différente de la réponse Husk de Unrelated String , également 27 octets .

J'avais retardé un moment de poster ceci, pour donner à tout nouveau Husker une ardoise propre pour essayer ce défi ... mais maintenant la Husketition est ouverte ...

Comment? *

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 octets

Edit: +33 octets à convertir en fonction récursive quand j'ai réalisé qu'il fallait répéter l' 8opération sur sa propre sortie jusqu'à ce qu'il n'y ait plus de 8s. 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)

Essayez-le en ligne!

Accepte l'argument nsous forme de chaîne. Erreurs pour les ns ne contenant pas de chiffres / caractères autres que 8.

4 Lyxal Oct 16 2020 at 13:18

Python 3 , 158 148 145 138 octets

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

Essayez-le en ligne!

-10 octets grâce à @ pavi2410 et à moi de ne pas être un idiot et de laisser accidentellement un espace supplémentaire à la suggestion de golf

et un autre -3 grâce à @ pavi2410

et un autre -7 grâce à @ pavi2410

4 Noodle9 Oct 16 2020 at 21:54

C (gcc) , 149 \$\cdots\$ 139137 octets

Sauvé 2 octets grâce à plafonnier !!!
Sauvegardé 8 octets grâce à 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;}

Essayez-le en ligne!

Explication (avant certains golfs)

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 octets

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

Essayez-le en ligne!

4 xash Oct 18 2020 at 07:32

J , 53 octets

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

Essayez-le en ligne!

Comment ça fonctionne

  • f^:_: jusqu'à ce que le résultat ne change pas, faites f.
  • '8'…(,g[=,)":: convertissez l'entrée en chaîne, ajoutez ,le caractère au début 8et exécutez-le gavec ceci comme argument de gauche et un masque de bits de 8caractères comme argument de droite.
  • (…".;._1)~: divisez la chaîne en groupes u;._1, qui commencent par 1 dans le masque de bits et les reconvertissent en nombres ".(à l'exclusion du 8).
  • *@#;._1#: parce que nous pourrions avoir des groupes vides ( 888), #ne prenez que ceux dont le #signe de longueur *est 1. (Il pourrait y avoir une meilleure approche.)
  • 2</\]: comparez <chaque groupe avec ses suivants, ce qui donne un masque de bits.
  • *_1x^0,: ajoutez un 0 au masque de bits et calculez x*(-1)^ypour chaque groupe xcomme yétant le résultat de la comparaison. Alors on obtient 3 1 2 -> 3 1 _2.
  • |@…+/: additionnez +/le résultat et prenez la valeur absolue |.
3 user Oct 16 2020 at 22:53

Scala , 94 90 octets

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

Essayez-le en ligne!

-4 octets en n'utilisant pas la splitméthode maudite de 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 octets

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

Essayez-le en ligne!

Ce n'est pas tout à fait ma première réponse Husk, mais c'est une traduction directe assez maladroite de l'une de mes tentatives de réponses Jelly, donc cela pourrait au moins servir de point de départ utile pour que quelqu'un se précipite et gagne la prime.

ω(                             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 octets

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

Il doit être stocké en tant que fonction fou dans un fichier fdans le répertoire de travail actuel.

Essayez-le en ligne!

3 ZsoltSzilagy Oct 18 2020 at 04:35

PHP, 290 octets

(Je suppose que vous ne devriez pas jouer au golf en 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;

Essayez-le en ligne

Non golfé:

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

Explication:

J'utilise array_reduce pour parcourir chaque chiffre, et j'utilise un tableau comme report pour avoir 3 points de données: les variables $a, $bande $sum, though they are unnamed as the elements of $c.

Si le chiffre actuel n'est pas un 8, je "l'ajoute" à mon "$b", otherwise I first compare $b à $a, add/subtract $b de $sum, and move the content of $b à $ a.

2 GalenIvanov Oct 16 2020 at 17:47

Rouge , 142 octets

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]

Essayez-le en ligne!

2 2014MELO03 Oct 16 2020 at 22:53

GolfScript , 32 octets

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

Essayez-le en ligne!

Chaque fois que l'algorithme est exécuté, le nombre reste le même ou il devient au moins 1 chiffre plus court. Cela signifie que nous pouvons exécuter l'algorithme une fois pour chaque octet au lieu de tester s'il a un 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 octets

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

Essayez-le

  • prend l'entrée sous forme de chaîne, il peut être facilement modifié pour prendre l'entrée sous forme de nombre mais cela ne fonctionnera pas avec de grands nombres

'' '

@=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 octets

-22 octets grâce à Traws

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

Essayez-le en ligne!

1 Neil Oct 16 2020 at 16:38

Retina 0.8.2 , 68 octets

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

1>`-

(1+)-\1

1

Essayez-le en ligne! Link comprend des cas de test plus petits (Retina doit faire une soustraction en unaire, ce qui est trop lent pour les cas plus grands). Explication:

{`

Répétez jusqu'à ce qu'il ne reste plus de 8s.

8+
-

Convertissez chaque série de 8s en a -.

^-|-$

Supprimer les -s de début et de fin .

\d+
$*

Convertissez les nombres restants en unaire.

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

Remplacez chacun -par un +sauf si le nombre suivant est supérieur.

O`\D1*

Triez les nombres à ajouter au début et les nombres à soustraire à la fin.

\+

Additionnez tous les nombres à additionner.

1>`-

Additionnez tous les nombres à soustraire ensemble.

(1+)-\1
   

Prenez la valeur absolue de la différence.

1

Convertissez-le en décimal.