Comer persistencia

Oct 16 2020

Intro

Encuentre el resultado del canibalismo numérico.

¿Por qué 6 tenía miedo de 7? Becase 7 89.

Su programa tendrá que encontrar el resultado de aplicar la 8operación (definida a continuación) en un número, repetidamente.

Relacionados , Sandbox

Desafío

Su entrada será un único entero positivo, n.

Debe encontrar cada uno 8en el número entero y sustituirlo por +o -según las siguientes condiciones.

  • eliminar todas las 8s al principio o al final de la cadena.
  • Si hay varios correos 8electrónicos, contraícelos en uno solo 8.
  • \$a\$y \$b\$son los trozos a la izquierda y derecha de 8respectivamente. Como 8es un operador, los números están delimitados por 8.
  • Si \$ a ≥ b,\$ 8se convierte +.
  • de lo contrario, se convierte en -.

Luego evalúa la expresión de izquierda a derecha y toma el valor absoluto.

Si el resultado tiene 8s, repita los pasos anteriores nuevamente hasta que no haya ninguno.

Por ejemplo, se 12384568789convierte en:

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

Por tanto, 335 es la respuesta final.

Ejemplo de entrada y salida

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

Aquí están los casos de prueba como una matriz:

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

Criterios de puntuación

Esto es código de golf . La respuesta más corta en cada idioma gana.

Respuestas

8 KevinCruijssen Oct 16 2020 at 17:29

05AB1E , 18 14 bytes

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

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

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

Gelatina , 20 18 bytes

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

¡Pruébelo en línea!

Pasé por otros 5 o 6 enfoques antes de que eval resultara ser el único que pude ponerme a trabajar ... y luego probé un giro diferente en mi segundo enfoque y es 2 bytes más corto.

Versión antigua: ṣ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 bytes

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

¡Pruébelo en línea!

Comentado

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

Cáscara , 27 26 25 bytes

Editar: -1 byte usando el Scombinador para reciclar el argumento de la función y moviendo la función auxiliar en línea, y luego -1 byte más con un poco de reordenamiento para poder usar el ocombinador en lugar de()

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

¡Pruébelo en línea!

Un enfoque ligeramente diferente a la respuesta de Cáscara de cadena no relacionada , también 27 bytes .

Dejé de publicar esto por un tiempo, para darle a cualquier nuevo Husker una pizarra limpia desde la cual probar este desafío ... pero ahora la Husketition está abierta ...

¿Cómo? *

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 bytes

Editar: +33 bytes para convertir a la función recursiva cuando me di cuenta de que debería repetir la 8operación en su propia salida hasta que no haya más 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)

¡Pruébelo en línea!

Acepta un argumento ncomo una cadena. Errores para mensajes de correo nelectrónico que no contengan caracteres o dígitos distintos de 8.

4 Lyxal Oct 16 2020 at 13:18

Python 3 , 158 148 145 138 bytes

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

¡Pruébelo en línea!

-10 bytes gracias a @ pavi2410 y a mí por no ser un idiota y dejar accidentalmente un espacio extra de la sugerencia de golf

y otro -3 gracias a @ pavi2410

y otro -7 gracias a @ pavi2410

4 Noodle9 Oct 16 2020 at 21:54

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

Ahorro de 2 bytes gracias a roofcat !!! Ahorro de
8 bytes gracias a 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;}

¡Pruébelo en línea!

Explicación (antes de algunos campos de golf)

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 bytes

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

¡Pruébelo en línea!

4 xash Oct 18 2020 at 07:32

J , 53 bytes

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

¡Pruébelo en línea!

Cómo funciona

  • f^:_: hasta que el resultado no cambie, f.
  • '8'…(,g[=,)":: convierte la entrada en una cadena, antepone ,el carácter 8y ejecuta gcon esto como el argumento de la izquierda y una máscara de bits de 8caracteres como el argumento de la derecha.
  • (…".;._1)~: divide la cadena en grupos u;._1, que comienzan con 1 en la máscara de bits y los vuelven a convertir en números ".(excluyendo el 8).
  • *@#;._1#: debido a que podríamos tener grupos vacíos ( 888), tome #solo aquellos cuyo #signum de longitud *sea ​​1. (Podría haber un enfoque más agradable).
  • 2</\]: compara <cada grupo con el siguiente, lo que da como resultado una máscara de bits.
  • *_1x^0,: Anteponer un 0 a la máscara de bits, y calcular x*(-1)^ypara cada grupo xcon yser el resultado de la comparación. Así lo conseguimos 3 1 2 -> 3 1 _2.
  • |@…+/: suma +/el resultado y toma el valor absoluto |.
3 user Oct 16 2020 at 22:53

Scala , 94 90 bytes

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

¡Pruébelo en línea!

-4 bytes al no usar el splitmétodo maldito 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

Cáscara , 27 bytes

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

¡Pruébelo en línea!

Esta no es mi primera respuesta de Husk, pero es una traducción directa bastante torpe de una de mis respuestas de Jelly intentadas, por lo que al menos podría servir como un punto de partida útil para que alguien entre y gane la recompensa.

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

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

Debe almacenarse como función fo en un archivo fen el directorio de trabajo actual.

¡Pruébelo en línea!

3 ZsoltSzilagy Oct 18 2020 at 04:35

PHP, 290 bytes

(Supongo que no deberías jugar al 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;

Pruébelo en línea

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

Explicación:

Utilizo array_reduce para caminar sobre cada dígito, y uso una matriz como acarreo para tener 3 puntos de datos: las variables $a, $by $sum, though they are unnamed as the elements of $C.

Si el dígito actual no es 8, lo "agrego" a mi "$b", otherwise I first compare $b a $a, add/subtract $b de $sum, and move the content of $b a $ a.

2 GalenIvanov Oct 16 2020 at 17:47

Rojo , 142 bytes

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]

¡Pruébelo en línea!

2 2014MELO03 Oct 16 2020 at 22:53

GolfScript , 32 bytes

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

¡Pruébelo en línea!

Cada vez que se ejecuta el algoritmo, el número permanece igual o se acorta al menos 1 dígito. Esto significa que podemos ejecutar el algoritmo una vez por cada byte en lugar de probar si tiene 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

Japón , 37 bytes

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

Intentalo

  • toma la entrada como una cadena, se puede modificar fácilmente para tomar la entrada como un número, pero no funcionará con números grandes

'' '

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

-22 bytes gracias a Traws

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

¡Pruébelo en línea!

1 Neil Oct 16 2020 at 16:38

Retina 0.8.2 , 68 bytes

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

1>`-

(1+)-\1

1

¡Pruébelo en línea! Link incluye casos de prueba más pequeños (Retina tiene que hacer una resta en unario, lo cual es demasiado lento para los casos más grandes). Explicación:

{`

Repita hasta que no queden 8mensajes.

8+
-

Convierta cada ejecución de 8sa a -.

^-|-$

Eliminar -s iniciales y finales .

\d+
$*

Convierte los números restantes a unario.

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

Reemplace cada uno -con un a +menos que el siguiente número sea mayor.

O`\D1*

Ordene los números que se agregarán al principio y los números que se restarán al final.

\+

Suma todos los números que se van a sumar.

1>`-

Suma todos los números que se van a restar.

(1+)-\1
   

Toma el valor absoluto de la diferencia.

1

Conviértelo a decimal.