Adição-subtração de números na cadeia


14

Pegue uma string como entrada e execute a adição / subtração de todos os dígitos da string e produza a soma dessas operações como resultado.

Regras

  • Os dígitos da sequência são lidos da esquerda para a direita
  • Se um dígito (n) for ímpar, faça a adição com o próximo dígito (n + n1)
  • Se um dígito (n) for par, execute a subtração com o próximo dígito (n - n1)
  • Se você atingiu o último dígito na sequência, execute a operação com o primeiro dígito na sequência
  • A saída será a soma de todos os valores resultantes
  • Se houver apenas um dígito na string, execute a operação sozinha (n + n ou nn)
  • Se não houver dígitos na sequência, a saída será 0

Exemplo

Input: r5e6o9mm!/3708dvc    
Process: (5+6) + (6-9) + (9+3) + (3+7) + (7+0) + (0-8) + (8-5)
Output: 32

Notas

  • A função ou o programa completo é aceito
  • O comprimento máximo de entrada dependeria do limite do seu idioma para uma entrada de string
  • Sem restrições na entrada de caracteres, mas apenas dígitos de meia largura contam para a saída
  • Menos bytes ganhos

4
Um casal mais exemplos seria bom também
dylnan

2
Eu recomendo adicionar um caso de teste que termine com um dígito ímpar.
Arnauld

3
Testcase sugerida: "", "0","1"
TSH

1
Podemos considerar a entrada como uma matriz de caracteres em vez de uma string? (Julia faz uma distinção entre os dois.)
sundar - Restabelece Monica

4
@sundar O consenso atual é que uma string seja definida como uma sequência de caracteres. Meu entendimento é que matrizes de caracteres são, portanto, permitidas por padrão, mesmo que seu idioma tenha um tipo de string nativo .
Arnauld

Respostas:


6

Geléia , 17 15 12 bytes

fØDV€ḂT‘ịƲSḤ

Experimente online!

Tente casos de teste.

O programa mantém apenas os dígitos que seguem um dígito ímpar e calcula o dobro da soma.

fØDV€ḂT‘ịƲSḤ   
f                   Remove anything that isn't...
 ØD                 a digit.
   V€               Cast each digit to an integer
         Ʋ          Monad:
     Ḃ              Parity of each digit.
      T             Indices of truthy elements (odd digits).
       ‘            Increment.
        ị           Index into list of digits.
                    Wraps to beginning and if there are no digits this returns 0.
          S         Sum.
           Ḥ        Double.

3

K (oK) , 47 43 40 31 bytes

Solução:

{+/(1_x,*x)*2*2!x^:(x-:48)^!10}

Experimente online!

Explicação:

Remova tudo da string que não é um número (enquanto também converte), módulo 2, multiplique por 2, multiplique com x girado por 1 e resuma.

{+/(1_x,*x)*2*2!x^:(x-:48)^!10} / solution
{                             } / lambda taking implicit x
                           !10  / range 0..10
                          ^     / except
                   (     )      / do this together
                    x-:48       / subtract 48 from x (type fudging char ascii value -> ints), save back into x
                x^:             / x except right, and save back to x
              2!                / modulo 2
            2*                  / multiply by 2
           *                    / multiply by
   (      )                     / do this together
        *x                      / first element of x
       ,                        / append to
      x                         / x
    1_                          / drop first (ie rotate everything by 1)
 +/                             / sum, add (+) over (/)

Solução ingênua:

Remova tudo da string que não é um número (enquanto também está convertendo), pegue a janela deslizante de dois itens, descubra se são ímpares ou pares, aplique adicionar / subtrair conforme apropriado e, em seguida, resuma.

{+/((-;+)2!x).'2':(1+#x)#x^:(x-:48)^!10}

Experimente online!

Notas:

  • -4 bytes graças a @ngn devido a uma maneira mais inteligente de filtrar a entrada
  • -3 bytes usando a janela deslizante em vez de remodelar
  • -9 bytes portando a solução da ngn (abordagem não ingênua)

1
x:48!x@&x in,/$!10->x^:(x-:48)^!10
NGN

Eu escrevi a solução em q / kdb + e então portado para oK ... talvez seja possível extrair mais alguns bytes disso ainda!
Streetster

1
Eu postei uma resposta separada em ngn / k, fique à vontade para trazer ideias a partir daí. Eu acho que oK vai acabar sendo o mais curto, pois meu analisador é um lixo no momento - ele não analisa a tarefa modificada corretamente. By the way, eu não estava ciente de ':como "janela deslizante" - interessante.
NGN

Você parece estar bem familiarizado com k. Se você quiser discutir coisas sobre programação de vetores com pessoas com a mesma opinião ou apenas assistir o resto de nós discutir - nós temos essa sala de bate-papo . A maior parte das brincadeiras é sobre APL, mas K e J também estão no tópico.
NGN



2

Powershell, 80 78 76 bytes

($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s

-2 bytes graças a Neil com solução Retina

-2 bytes obrigado AdmBorkBork

Script de teste:

$f = {
($d="$args"-split'\D*'-ne'')+$d[0]|?{$p-match'[13579]';$p=$_}|%{$s+=2*$_};$s
}

&$f 'r5e6o9mm!/3708dvc'

Explicação

Primeiro de tudo: ele deve adicionar 2 * n se o dígito anterior for ímpar e 0 se o dígito anterior for par.

($d="$args"-split'\D*'-ne'')+ # let $d is array contains digits only, each element is a digit
$d[0]|                        # apend first digit to the end of the array
?{                            # where for each digit
    $p-match'[13579]'         # predicate is 'previous digit is odd' (it is false on the first iteration because $p is null)
    $p=$_                     # let previous digit is current
}|
%{                            # for each digit matched to the predicate
    $s+=2*$_                  # add current digit multiply 2 to $s. 
}
$s                            # return sum

Extra, 99 bytes

Inspirado por @Neil. Somente dígitos de correspondência de expressão regular com 'dígito anterior são ímpares'. Matchesé uma variável automática .

param($d)$d+($d-match'\d')+$Matches[0]|sls '(?<=[13579]\D*)\d'-a|%{$_.Matches.Value|%{$s+=2*$_}};$s

1
Salve um byte trocando |?{$_}por -ne''outro movendo-o $d="$args"-split'\D*'-ne''para parênteses ($d="$args"-split'\D*'-ne'')+$d[0].
AdmBorkBork

2

MATL , 18 17 bytes

t4Y2m)!Ut1YSof)sE

Experimente online!

(-1 byte graças a Luis Mendo / Giuseppe / ambos!)

Explicação:

     % Implicit input
 t   % duplicate input
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc']
 4Y2 % push inbuilt literal, characters '0':'9'
     % stack: ['r5e6o9mm!/3708dvc' 'r5e6o9mm!/3708dvc' '0123456789']
 m)  % extract only characters from input that belong to '0':'9'
     % stack: ['5693708']
 !U  % transpose and convert each value from string to number
     % stack: [5 6 9 3 7 0 8]
 t   % duplicate that
 1YS % circular shift by 1
     % stack: [[5 6 9 3 7 0 8] [8 5 6 9 3 7 0]]
 o   % parity check - 1 for odd, 0 for even
     % stack: [[5 6 9 3 7 0 8] [0 1 0 1 1 1 0]]
 f   % find non-zero value indices in last array
     % stack: [[5 6 9 3 7 0 8] [2 4 5 6]]
 )   % index at those places in the first array
 s   % sum
 E   % multiply by 2
     % (implicit) convert to string and display

A idéia básica é que os números que seguem números pares podem ser ignorados, enquanto os que seguem números ímpares são duplicados - e o resultado final é a soma desses valores duplicados.

Eu não pensei que fapós a verificação de paridade oseria necessário, mas por algum motivo o MATL não vê a matriz de 0 e 1 resultante da omatriz lógica, em vez disso, leva-os como índices e índices numéricos para as posições 1e end.


Eu acho que você pode usar em !Uvez de 48-. A transposição não parece causar nenhum dano aqui. opara doubleentrada é apenas mod(...,2), então a saída é double. Bom NaNtruque de entrada! Se isso é feito para resolver a saída estranha em STDOUT, Dennis tinha uma idéia e provavelmente irá corrigir isso em breve
Luis Mendo

!Uem vez de48-
Giuseppe

@LuisMendo welp, você me venceu!
Giuseppe

@Giuseppe :-D :-D
Luis Mendo

Obrigado a ambos, editado. @LuisMendo Quando, então, ofornece uma saída de matriz lógica - ou não? (Devo confessar que nunca realmente examinei o sistema de tipos numéricos do MATLAB.) E sim, pensei NaNem criar uma sentinela agradável, já que é improvável que seja uma entrada real em qualquer lugar, mas é bom saber que não será necessário por muito mais tempo !
sundar - Restabelece Monica

2

K (ngn / k) , 33 bytes

{+/(1_x,*x)*2*2!x:-48+x^x^,/$!10}

Experimente online!

{ } é uma função com argumento x

!10 é a lista 0 1 ... 9

$ converter em strings

,/ concatenar

x^significa xsem o que está à direita

x^x^significa xinterseção com o que está à direita, ou seja, mantenha apenas os dígitosx

-48+subtrair 48, que é o código ASCII de"0"

x: atribuir a x

2! mod 2

2* multiplicado por 2

1_x,*xé uma gota de: xseguido pelo primeiro de x; ou seja, xgirado para a esquerda em um passo

+/ soma


2

Japt (v2.0a0), 25 19 bytes

-6 bytes graças a Shaggy .

kè\D
íÈ°*2*Y°u}Ué)x

Experimente aqui .

Desta vez, funciona sem dígitos! Entrada é uma lista de caracteres.


19 bytes , incluindo a mudança para o Japt v2. xPorém, não estou satisfeito com a matriz na função. Ping me no chat, se você tiver alguma dúvida.
Shaggy

Espere, notei que isso não funcionará se a entrada não contiver nenhum dígito.
Salsicha

Além disso, onde está a fonte da v2.0a0, @Shaggy? Não consigo encontrá-lo no repositório.
LegionMammal978

Esta é a v1 e esta é a v2.
Shaggy

Caso você tenha perdido no chat, eu reduzi para 12 bytes para você.
Shaggy

2

05AB1E , 12 9 bytes

Economiza 1 byte sobre o método ingênuo, utilizando o truque de paridade de dylnan
Economizou 3 bytes graças ao Sr. Xcoder

þDÁ€ÉÏSO·

Experimente online!

Explicação

þ              # push only digits of input
 D             # duplicate
  Á            # rotate right
   ۃ          # get the parity of each
     Ï         # keep only true items
      SO       # calculate digit-sum
        ·      # double

Hmm, que þÀIþ€ÉÏSO·, þÀDÁ€ÉÏSO·, þÀ¹þ€ÉÏSO·ou þÀsþ€ÉÏSO·passar todos os casos de teste para -2 bytes?
Mr. Xcoder

@ Mr.Xcoder: Ah, sim. Agradável! Podemos até fazer þDÁ€ÉÏSO·para -3 :)
Emigna

1

Retina , 37 bytes

(\d).*
$&$1
L$`(?<=[13579]\D*).
2**
_

Experimente online! Explicação:

(\d).*
$&$1

Anexe uma duplicata do primeiro dígito.

L$`(?<=[13579]\D*).

Corresponde a qualquer coisa cujo primeiro dígito anterior seja ímpar.

2**

Converta todas as correspondências em unárias e duplique-as. (Os dígitos não são tratados como zero.)

_

Pegue a soma. Se não houver correspondências, isso produzirá zero, conforme necessário.

O melhor que pude fazer no Retina 0.8.2 foi de 44 bytes:

[^\d]

(.).*
$&$1
(?<![13579]).

.
$*
.
..
.

Experimente online! Explicação:

[^\d]

Exclua sem dígitos.

(.).*
$&$1

Anexe uma cópia do primeiro dígito.

(?<![13579]).

Exclua os dígitos que não seguem um dígito ímpar.

.
$*

Converta para unário.

.
..

Dobre-os.

.

Pegue a soma.


Receio que o resultado será incorreto se o último dígito não é estranho
Mazzy

1
@mazzy Quando diz o último dígito, quer dizer antes ou depois de copiar o primeiro dígito até o fim?
611 Neil

'até o fim'. a etapa 'Anexar uma duplicata do primeiro dígito' está copiando até o final? Está bem. legal. Obrigado
mazzy


1

JavaScript (ES6), 56 bytes

Recebe a entrada como uma matriz de caracteres.

s=>s.map(c=>1/c?r+=p*(p=c*2&2,n=n||c,c):0,n=p=r=0)|r+p*n

Experimente online!

Comentado

s =>                     // given the input array s[]
  s.map(c =>             // for each character c in s[]:
    1 / c ?              //   if c is a digit:
      r +=               //     update r:
        p * (            //       p = either 0 or 2 (always 0 on the 1st iteration)
          p = c * 2 & 2, //       p = 0 if c is even, 2 if c is odd
          n = n || c,    //       if n is still equal to 0 (as an integer), set it to c
          c              //       compute p * c
        )                //     add the result to r
    :                    //   else:
      0,                 //     do nothing
    n = p = r = 0        //   n = first digit, p = previous digit, r = result
  )                      // end of map()
  | r + p * n            // compute the last operation with the 1st digit and add it to r

1

JavaScript (Node.js) , 85 84 83 82 bytes

-1 bytes graças a ovs

s=>(s.match(/\d/g)||[]).reduce((r,n,i,a)=>r+(+n)+a[a[++i]!=null?i:0]*-(1-n%2*2),0)

Experimente online!

Pega a entrada da string, localiza os dígitos como uma matriz de caracteres ou retorna uma matriz vazia, se nenhuma for encontrada, e usa coerção de tipo para garantir que os valores sejam adicionados / subtraídos corretamente. A pesquisa direta pré-incrementa o índice e usa uma verificação nula por questões de concisão, e a parte final verifica se o número é ímpar ou uniforme para forçar a adição ou subtração (+ e - é -, etc)


n-0pode ser+n
ovs 06/07

Bem-vindo ao PPCG!
Conor O'Brien

1

R , 58 bytes

function(x,y=strtoi(x[x%in%0:9]))sum(c(y[-1],y[1])*y%%2*2)

Experimente online!


67 bytes se você não se importa com a arraysaída.
Giuseppe

1
hmm, na verdade, você não pode usar o produto escalar por causa da matriz vazia, xxxportanto, são 68 bytes usando a alteração na indexação apara gerar y.
Giuseppe

@Giuseppe: modificado, obrigado :)
digEmAll

@ Giuseppe: Peço a sua opinião, já que você é um jogador de código mais sábio ... pelos comentários, parece que podemos usar um vetor de caracteres; nesse caso, 61 bytes são possíveis: Experimente on-line! O que você acha ?
precisa

use em strtoivez de as.double, mas sim, tudo bem.
Giuseppe

0

Perl 5 , 48 bytes

$;=$;[++$-%@;],$\+=$_%2?$_+$;:$_-$;for@;=/\d/g}{

Experimente online!

Eu gosto bastante de como isso parece enigmático, mas é um loop bastante direto em torno de todos os números na string.



0

C Sharp 180 bytes

Isso não é muito bom golfe, lol.

s=>{var q=new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));q.Enqueue(q.First());int t,o=0;o=q.Dequeue();try{while(true){t+=o+(o%2==0?-1:1)*(o=q.Dequeue());}}catch{return t;}}

Ungolfed:

var q = new Queue<int>(s.Where(Char.IsNumber).Select(n=>n-48));
int t,o=0;

q.Enqueue(q.First());    
o=q.Dequeue();

try{
    while(true){
        t += o + (o%2==0?-1:1) * (o=q.Dequeue());
    }
}
catch {
    return t;
}

0

Stax , 14 bytes

ÿ←«4é■≥B▬ê→█T♥

Execute e depure

Descompactado, não jogado e comentado, é assim.

Vd|&    filter out non-digits
c|(\    zip into pairs after rotating right
F       for each digit pair
  B2%s  first-of-pair % 2, then swap top two stack elements
  eH*   eval digit as integer, double, then multiply
  +     add to running total

Execute este


0

JavaScript (ES6), 52 bytes

s=>s.filter(t=>1/t&&~(a+=u*t,u=t%2),a=u=0)[0]*u+a<<1

Espera entrada como uma matriz de caracteres. Advertência: Devido ao uso de deslocamento de bits, a saída tem um limite superior de2^31-1

Experimente online!

Explicação

Dobra essencialmente a soma dos dígitos após valores ímpares.

s => s.filter(             // filter to preserve the first digit
    t =>
        1/t &&             // short-circuits if NaN
        ~(                 // coerce to truthy value
            a += u * t,    // adds value only if previous digit is odd
            u = t%2        // store parity of current digit
        ),
    a = u = 0
)[0]                       // first digit
* u + a
<< 1                       // bit-shift to multiply by 2 (also coerces a NaN resulting from a string devoid of digits to 0)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.