Persistência alimentar

Oct 16 2020

Introdução

Encontre o resultado do canibalismo numérico.

Por que 6 ficou com medo de 7? Becase 7 89.

Seu programa terá que encontrar o resultado da aplicação da 8operação (definida abaixo) em um número, repetidamente.

Relacionado , Sandbox

Desafio

Sua entrada será um único inteiro positivo, n.

Você precisa encontrar cada um 8no inteiro e substituí-lo +ou com -base nas seguintes condições.

  • remova todos os 8s no início ou no final da string.
  • Se houver vários 8s, agrupe-os em um único 8.
  • \$a\$e \$b\$são os pedaços à esquerda e à direita do, 8respectivamente. Como 8é um operador, os números são delimitados por 8.
  • If \$ a ≥ b,\$ 8torna-se +.
  • caso contrário, torna-se -.

Em seguida, avalie a expressão da esquerda para a direita e obtenha o valor absoluto.

Se o resultado tiver algum 8s, repita as etapas acima novamente até que não haja nenhum.

Por exemplo, 12384568789torna-se:

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

Portanto, 335 é a resposta final.

Exemplo de entrada e saída

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

Aqui estão os casos de teste como uma matriz:

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

Critérios de pontuação

Este é o código de golfe . A resposta mais curta em cada idioma ganha.

Respostas

8 KevinCruijssen Oct 16 2020 at 17:29

05AB1E , 18 14 bytes

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

Experimente online ou verifique todos os casos de teste .

Explicação:

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

Jelly , 20 18 bytes

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

Experimente online!

Passei por 5 ou 6 outras abordagens antes que eval acabasse sendo a única que consegui fazer funcionar ... e então tentei uma rodada diferente na minha segunda abordagem e é 2 bytes a menos.

Versão antiga: ṣ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

Experimente online!

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

Husk , 27 26 25 bytes

Editar: -1 byte usando o Scombinador para reciclar o argumento da função e movendo a função auxiliar em linha, e então -1 byte por um pouco de rearranjo para ser capaz de usar o ocombinador em vez de()

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

Experimente online!

Uma abordagem ligeiramente diferente para a resposta do Husk da Unrelated String , também de 27 bytes .

Eu tinha evitado postar isso um pouco, para dar a qualquer novo Husker uma lousa em branco para tentar este desafio ... mas agora o Husketition está aberto ...

Como? *

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

Edit: +33 bytes para converter em função recursiva quando percebi que deveria repetir a 8operação em sua própria saída até que não houvesse mais 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)

Experimente online!

Aceita argumento ncomo string. Erros para ns que não contêm nenhum dígito / caracteres diferente 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)))

Experimente online!

-10 bytes graças a @ pavi2410 e por não ser um idiota e acidentalmente deixar um espaço extra para a sugestão de golfe

e outro -3 graças a @ pavi2410

e outro -7 graças a @ pavi2410

4 Noodle9 Oct 16 2020 at 21:54

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

Economizei 2 bytes graças ao tetocat !!!
Economizei 8 bytes graças ao 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;}

Experimente online!

Explicação (antes de alguns jogos de golfe)

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

Experimente online!

4 xash Oct 18 2020 at 07:32

J , 53 bytes

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

Experimente online!

Como funciona

  • f^:_: até que o resultado não mude, faça f.
  • '8'…(,g[=,)":: converte a entrada em uma string, precede ,o caractere 8e executa gcom isso como o argumento esquerdo e uma máscara de bits de 8caracteres como o argumento direito.
  • (…".;._1)~: divide a string em grupos u;._1, que começam com 1 na máscara de bits e os converte de volta em números ".(excluindo o 8).
  • *@#;._1#: porque poderíamos ter grupos vazios ( 888), pegue #apenas aqueles, cujo #signum de comprimento *é 1. (Pode haver uma abordagem mais agradável.)
  • 2</\]: compare <cada grupo com o seguinte, resultando em uma máscara de bits.
  • *_1x^0,: acrescente um 0 à máscara de bits e calcule x*(-1)^ypara cada grupo xcomo ysendo o resultado da comparação. Então nós entendemos 3 1 2 -> 3 1 _2.
  • |@…+/: some +/o resultado e obtenha o 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

Experimente online!

-4 bytes por não usar o splitmétodo amaldiçoado 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 bytes

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

Experimente online!

Esta não é exatamente a minha primeira resposta Husk, mas é uma tradução direta bastante desajeitada de uma das minhas tentativas de respostas Jelly, então pode pelo menos servir como um ponto de partida útil para alguém se lançar e ganhar a 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

Ele deve ser armazenado como uma função fou em um arquivo fno diretório de trabalho atual.

Experimente online!

3 ZsoltSzilagy Oct 18 2020 at 04:35

PHP, 290 bytes

(Acho que você não deveria jogar golfe em 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;

Experimente online

Ungolfed:

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

Explicação:

Eu uso array_reduce para percorrer cada dígito e uso um array como transporte para ter 3 pontos de dados transportados: as variáveis $a, $banda $sum, though they are unnamed as the elements of $c.

Se o dígito atual for diferente de 8, eu o "adiciono" ao meu$b", otherwise I first compare $b para $a, add/subtract $b de $sum, and move the content of $b a $ a.

2 GalenIvanov Oct 16 2020 at 17:47

Vermelho , 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]

Experimente online!

2 2014MELO03 Oct 16 2020 at 22:53

GolfScript , 32 bytes

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

Experimente online!

Cada vez que o algoritmo é executado, o número permanece o mesmo ou fica pelo menos 1 dígito menor. Isso significa que podemos executar o algoritmo uma vez para cada byte em vez de testar se ele tem um 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 bytes

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

Tente

  • aceita a entrada como uma string, pode ser facilmente modificado para receber a entrada como um número, mas não funcionará com 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 graças ao Traws

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

Experimente online!

1 Neil Oct 16 2020 at 16:38

Retina 0.8.2 , 68 bytes

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

1>`-

(1+)-\1

1

Experimente online! Link inclui casos de teste menores (Retina tem que fazer subtração em unário, que é muito lento para casos maiores). Explicação:

{`

Repita até que não haja mais nada 8.

8+
-

Converta cada execução de 8s em a -.

^-|-$

Exclua os -s iniciais e finais .

\d+
$*

Converta os números restantes em unários.

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

Substitua cada -um por um +, a menos que o número a seguir seja maior.

O`\D1*

Classifique os números a serem adicionados no início e os números a serem subtraídos no final.

\+

Adicione todos os números a serem somados.

1>`-

Some todos os números a serem subtraídos juntos.

(1+)-\1
   

Pegue o valor absoluto da diferença.

1

Converta em decimal.