Saída da inclinação cumulativa de uma string


12

Desafio

Dada uma string como Hello World!, decompô-lo em seus valores de caracteres: 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33.

Em seguida, calcular a diferença entre cada par consecutivo de caracteres: 29, 7, 0, 3, -79, 55, 24, 3, -6, -8, -67.

Finalmente, somá-los e imprimir o resultado final: -39.

Regras

  • Aplicam-se brechas padrão
  • Não é possível usar funções pré-criadas que executam essa tarefa exata
  • Soluções criativas incentivadas
  • Diverta-se
  • Isso é marcado como , a resposta mais curta em bytes vence, mas não será selecionada.

16
A observação de Dennis mostra que esta tarefa é formulada de uma maneira mais complicada do que o necessário.
Greg Martin

Um idioma pode aceitar entrada como uma matriz de caracteres, mesmo que seja compatível com tipos de string?
puxão

@Poke desculpe, tem que ser uma seqüência de caracteres
dkudriavtsev

@ GregMartin Na verdade, eu não percebi isso até mais tarde. O desafio deve permanecer assim.
dkudriavtsev 27/09/16

@DJMcMayhem É bom saber que todas as outras formas de saída são permitidas.
dkudriavtsev 27/09/16

Respostas:


38

Python, 29 bytes

lambda s:ord(s[-1])-ord(s[0])

A soma das diferenças forma uma série telescópica; portanto, a maioria das somas é cancelada e
(s 1 - s 0 ) + (s 2 - s 1 ) +… + (s n-1 - s n-2 ) + (s n - s n-1 ) = s n - s 0 .

Se utilizar uma sequência de bytes como entrada, é permitido

lambda s:s[-1]-s[0]

também funcionará para 19 bytes .

Teste ambos em Ideone .


Isso imprime o resultado?
dkudriavtsev 27/09/16

4
Em um REPL, acho que sim. A forma pretendida de saída é um valor de retorno, que é um dos nossos métodos padrão de saída. Se isso não for permitido, a maioria das respostas nos idiomas de produção é inválida.
Dennis

22

MATL , 2 bytes

ds

Experimente online!

Explicação:

dobtém a diferença entre caracteres consecutivos e ssoma a matriz resultante. Em seguida, o valor no topo da pilha é impresso implicitamente. Não há muito mais a dizer sobre isso.

Curiosamente, mesmo que Dennis tenha descoberto um atalho incrível, usá-lo seria significativamente mais longo no MATL.


9

Geléia , 3 bytes

OIS

Experimente online!

Pegue os Orinais dos caracteres da string de entrada, depois os Incrementos dessa lista e, em seguida, o Sum dessa lista.


Sim, imprimir o resultado (e receber informações em primeiro lugar) acontece implicitamente no Jelly.
Lynn

6

MATLAB, 16 bytes

@(x)sum(diff(x))

Isso cria uma função anônima chamada ansque pode ser chamado como: ans('Hello world!').

Aqui está uma demonstração on - line no Octave que requer um byte adicional +para converter explicitamente a sequência de entrada em uma matriz numérica antes de calcular a diferença de elemento para elemento


4

Python, 63 bytes

x=map(ord,input())
print sum(map(lambda(a,b):b-a,zip(x,x[1:])))

Ideone it!


3

Cubix , 13 bytes

Cubix é uma linguagem bidimensional envolvida em um cubo.

i?u//O-t#;/.@

Teste online! Isso é mapeado para a seguinte rede de cubos:

    i ?
    u /
/ O - t # ; / .
@ . . . . . . .
    . .
    . .

Onde o IP (ponteiro de instruções) começa no canto superior esquerdo da face esquerda.

Como funciona

Primeiro, o IP atinge o espelho /que o redireciona para a iface superior. A face superior é um loop que insere códigos continuamente até que o EOF seja alcançado. Quando a entrada está vazia, o resultado ié -1; o IP vira à esquerda a partir do ?, pressionando o /botão na extremidade direita e seguindo os seguintes comandos:

  • ; - Pop o item superior (-1).
  • # - Empurre o comprimento da pilha.
  • t- Coloque o item superior e obtenha o item nesse índice na pilha. Isso puxa o item inferior.
  • - Subtrair.
  • O - Saída como um número inteiro.
  • /- Desvia o IP para o @, que finaliza o programa.

3

C #, 22 bytes

s=>s[s.Length-1]-s[0];

Código fonte completo com caso de teste:

using System;

namespace StringCumulativeSlope
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string,int>f= s=>s[s.Length-1]-s[0];
            Console.WriteLine(f("Hello World!"));
        }
    }
}

C # com LINQ, 17 bytes

Uma versão mais curta, usando LINQ, graças ao hstde :

s=>s.Last()-s[0];

No entanto, é necessária uma importação extra:

using System.Linq;

2
s=>s.Last()-s[0];seria apenas 17 bytes
hstde 27/09/16

3

Ruby, 23 bytes

->s{s[-1].ord-s[0].ord}

Atribua a uma variável como f=->s{s[-1].ord-s[0].ord}e chame comof["Hello World!"]

Usa a observação de Dennis sobre séries telescópicas.


Você não precisa imprimir a saída, apenas devolvê-la, para que possa se livrar $><<.
Jordânia

1
Sim, eu também li a pergunta. Felizmente, existe um amplo consenso sobre a definição de "saída" (veja também: as muitas respostas nesta página que retornam ao invés de imprimir um valor). Mas ei, é o seu código.
Jordânia

2

reticular, 12 bytes

idVc~@qVc-o;

Experimente online!

Usando a observação de Dennis , podemos reduzir um processo iterativo para outro mais simples.

idVc~@qVc-o;
i             take input
 d            duplicate
  V           pop input copy, push last character
   c          get its char code
    ~         put it under the input in the stack
     @q       reverse the item at the top of the stack
       V      get the last item of that (first item of input)
        c     convert to char
         -    subtract
          o   output
           ;  and terminate

2

Brain-Flak , 51 bytes

48 bytes de código mais três bytes para o -asinalizador, o que habilita a entrada ASCII (mas a saída decimal. Como conveniente.: D)

{([{}]({})<>)<>}<>{}([]<>){({}[()])<>({}{})<>}<>

Experimente online!

Este é um pouco mais difícil do que minha outra resposta, haha. Vamos passear por ele.

{           While the top of the stack is nonzero:
 (            Push:
  [{}]          The top of the stack times negative one. Pop this off.
  ({})          Plus the value on top of the stack, which is duplicated to save for later.
  <>          On to the other stack
 )
 <>         Move back to the first stack
}
<>          After the loop, move back again.
{}          We have one extra element on the stack, so pop it
([]<>)      Push the height of the alternate stack back onto the first stack
{           While the top of the stack is nonzero:
 ({}[()])     Decrement this stack
 <>           Move back to the alternate stack
 ({}{})       Sum the top two elements
 <>           Move back tothe first stack
}
<>          Switch back to the stack holding the sum


2

Braquilog , 7 bytes

@c$)@[-

Experimente online!

Explicação

@c        Convert "Hello World!" to [72,101,108,108,111,32,87,111,114,108,100,33]
  $)      Circular permute right: [33,72,101,108,108,111,32,87,111,114,108,100]
    @[    Take a prefix of the list
      -   Subtract

Como subtrair funciona apenas para uma entrada de dois números inteiros, será bem-sucedido quando o prefixo selecionado for [33, 72].


2

Haskell, 32 bytes

g=fromEnum
f t=g(last t)-g(t!!0)

@nimi É o mesmo.
xnor

2

R, 69 43 32 bytes

Uma resposta muito não competitiva, embora eu achasse divertido mostrar uma possível solução em R.

sum(diff(strtoi(sapply(strsplit(readline(),"")[[1]],charToRaw),16L)))

O único aspecto interessante desta resposta é o uso de sapplye charToRaw. Primeiro, divido a string em um vetor de caracteres que desejo converter em suas representações inteiras ASCII. A charToRawfunção não é vetorizada em R e, em vez de fazer um loop sobre cada valor no vetor mencionado acima, sapplyque efetivamente vetoriza a função. Posteriormente, pegue a 1ª diferença e depois some.


Editar: charToRawtransforma uma string em um vetor, onde cada elemento é a representação bruta de cada caractere, portanto, não há necessidade de usar strsplitesapply

sum(diff(strtoi(charToRaw(readline()),16)))

Edit2: Acontece que existe uma maneira ainda melhor, a função utf8ToInt(x)faz exatamente o strtoi(charToRaw(x),16)que significa que podemos salvar mais alguns bytes (idéia retirada da resposta de @ rturnbull para outra pergunta):

sum(diff(utf8ToInt(readline())))

2

Perl, 19 bytes

Inclui +1 para -p

Dê entrada no STDIN sem nova linha final

echo -n "Hello World!" | slope.pl; echo

slope.pl:

#!/usr/bin/perl -p
$_=-ord()+ord chop

Se você tem certeza de que a string de entrada possui pelo menos 2 caracteres, esta versão de 17 bytes também funciona:

#!/usr/bin/perl -p
$_=ord(chop)-ord

2

NodeJS, 82 bytes

x=process.argv[2],a=[],t=0;for(y in x)a[y]=x.charCodeAt(y),t+=y!=0?a[y]-a[y-1]:0

Explicação:

x = process.argv[2] // Get the input
a=[], // Initializes an array to store the differences' values.
t=0;  // Initializes a variable to store the total of the differences
for(y in x) // Iterates over the string as an array of characters
    a[y]=x.charCodeAt(y) // Transforms the input into an array of integers
    t+=y!=0?a[y]-a[y-1]:0 // Add the difference of the last two characters, except at the first iteration

JavaScript, 79 bytes

f=x=>{a=[],t=0;for(y in x)a[y]=x.charCodeAt(y),t+=y!=0?a[y]-a[y-1]:0;return t}

A mesma idéia acima com uma entrada de função em vez de um argumento.


Desculpe, mas você não pode assumir que xé a entrada. Você realmente precisa obter informações.
Rɪᴋᴇʀ

Isso funciona assim?
Alexis_A 26/09/16

Sim, isso funciona muito bem!
Rɪᴋᴇʀ

1
Outra maneira aceitável de obter entrada é criar uma função. Por exemplo, f=x=>{...;return t}para salvar 2 bytes;)
joeytwiddle

2

JavaScript ES6, 42 39 bytes

f=
     s=>s[x='charCodeAt'](s.length-1)-s[x]();
;

console.log(f.toString().length);      // 39
console.log(f('Hello World!'))         // -39

Usando a observação @Dennis sobre somas de telescópio.

Penso que, neste caso, a solução trivial é a mais curta.

Economizou 3 bytes ao se livrar da charCodeAtrepetição, conforme sugerido por @Neil.


O melhor que pude fazer foi s=>s.slice(-1).charCodeAt()-s.charCodeAt()o mesmo comprimento.
Neil

Na verdade, charCodeAté bastante longo, provavelmente existe uma maneira de salvar bytes, evitando a repetição.
Neil

@ Neil Obrigado pela sugestão, que me salvou 3 bytes.
precisa saber é

Uma abordagem ligeiramente recursiva tem alguns bytes a mais:f=s=>(s[1]?-f(s.slice(-1)):0)-s.charCodeAt()
ETHproductions

2

Quarto, 28 bytes

: f depth 1- roll swap - . ;

Leva uma lista de caracteres na pilha (método padrão de obtenção de parâmetros de Forth). Os caracteres são usados ​​de forma que a parte superior da pilha seja o primeiro caractere da string. Movo a parte inferior da pilha para o topo, troco, depois subtraio e imprimo. O lixo é deixado na pilha e a saída é impressa em stdout.

Se cada caractere fosse empurrado para a pilha em ordem e não na ordem inversa, o programa seria 2 bytes mais curto. Não tenho certeza se isso é permitido, porque normalmente você envia argumentos na ordem inversa.

Experimente online

Chamado assim:

33 100 108 114 111 87 32 111 108 108 101 72 f

2

Java, 42

int f(char[]c){return c[c.length-1]-c[0];}

Ungolfed:

  int f(char[] c) {
    return c[c.length - 1] - c[0];
  }

Explicação:

Isso usa o mesmo princípio que o telescópio:

sum =
  c[4] - c[3]
+        c[3] - c[2]
+               c[2] - c[1]
+                      c[1] - c[0]
= c[4]                      - c[0]

Generalizada para qualquer sequência de caracteres n, a resposta é c[n-1] - c[0]porque todas as coisas no meio são canceladas.


2

PHP 7.1, 33 31 bytes

Usa deslocamentos negativos de string implementados no PHP 7.1.

echo ord($argn[-1])-ord($argn);

Execute assim:

echo 'Hello World!' | php -nR 'echo ord($argn[-1])-ord($argn);';echo

Tweaks

  • 2 bytes salvos usando $argn

1

RProgN , 142 Bytes, Não concorrente

function tostack 'b' asoc stack 'a' asoc 0 'v' asoc b pop byte 'o' asoc b len while [ v o b pop byte ] 'o' asoc - + 'v' asoc b len end [ v end

Não concorrente, pois o comando 'tostack' foi adicionado após a descoberta desse desafio (mesmo que tenha uma contagem terrível de bytes)

Casos de teste

Hello, World!
-39

Cool, huh?
-4

Explicação

function                        # Push the function between this and end to the stack
    tostack 'b' asoc            # Convert the implicit input to a stack, associate it with 'b'
    0 'v' asoc                  # Push 0 to the stack, associate it with 'v'
    b pop byte 'o' asoc         # Pop the top value of b (The end of the input), get the byte value, associate it with 'o'.
    b len                       # Push the size of b to the stack
    while [                     # While the top of the stack is truthy, pop the top of the stack
        v                       # Push v to the stack
            o                   # Push o to the stack
            b pop byte          # Pop the top value of b, push the byte value of that to the stack
            ] 'o' asoc          # Push a copy of the top of the stack, associate it with 'o'
            -                   # Subtract the top of the stack from one underneith that, In this case, the old value of o and the byte.
        +                       # Sum the top of the stack and underneith that, that is, the difference of the old value and new, and the total value
        'v' asoc                # Associate it with 'v'
        b len                   # Push the size of b to the stack (which acts as the conditional for the next itteration)
    end [                       # Pop the top of the stack, which will likely be the left over size of b
    v                           # Push the value of v to the top of the stack
end                             # Implicitely returned / printed

RProgN é uma linguagem esotérica em que tenho trabalhado com a Notação Polonesa Reversa em mente. Atualmente, é bastante detalhado, com a atribuição de variáveis ​​com 4 caracteres e, portanto, pretendo adicionar no futuro um pouco de açúcar sintático.

Além disso, RProgN acessa implicitamente argumentos da pilha e os retorna da mesma maneira. Quaisquer dados de sequência deixados na pilha após a conclusão do programa são impressos implicitamente.


"Um pouco de açúcar" realmente mudou de forma nos poucos meses que isso levou. Essa coisa toda é agora ~{bid☼[+e isso é um pouco adorável.
AT6 de

1

PHP, 36 bytes

<?=ord(strrev($s=$argv[1]))-ord($s);
  • Todos os caracteres, exceto o primeiro e o último, são adicionados e subtraídos uma vez cada.
    → soma das diferenças == diferença entre o primeiro e o último caractere
  • ord()no PHP opera com o primeiro caractere de uma string
    → não é necessário reduzi-la explicitamente para um único caractere

1

Brain-Flak , 34 32 + 3 = 35 bytes

+3 por causa do -asinalizador necessário para o modo ascii.

Experimente online

(([][()]){[{}{}]({})([][()])}<>)

Estranhamente, é mais eficiente usar a definição usada nas especificações em vez do "truque" de subtrair primeiro do último.

Isso funciona fazendo exatamente isso.

(                           )  Push
 ([][()]){[{}]...([][()])}     While the stack has more than one item
  [{}]({})                     Subtract the top from a copy of the second
                          <>   Switch

1

CJam , 8 5 bytes

Muito obrigado a Dennis por duas sugestões que removeram 3 bytes

l)\c-

Experimente online!

Explicação

Calcula o último valor menos o primeiro valor.

l        e# Read line as a string
 )       e# Push original string except last char, then last char
  \      e# Swap
   c     e# Convert to char: gives the first element of the string
    -    e# Subtract. Implicitly display

Se você usar em )vez de W=, não precisará do _. Além disso, ccomo um atalho para 0=.
Dennis

@ Dennis Muito obrigado!
Luis Mendo

1

Haskell, 36 bytes

sum.(tail>>=zipWith(-)).map fromEnum

uso:

Prelude> (sum.(tail>>=zipWith(-)).map fromEnum)"Hello World!"
-39


Haskell (Lambdabot), 31 bytes

sum.(tail>>=zipWith(-)).map ord

Receio que isso não seja uma função adequada. É apenas um trecho. sum.(tail>>=zipWith(-)).map fromEnumpor exemplo é uma função.
nimi

@nimi A questão não pediu uma função própria
Cabeção

A pergunta não pediu nada, então os padrões entram em ação, que são programas ou funções completos, mas não trechos .
nimi

1

Zsh , 22 bytes

c=${1[-1]}
<<<$[#1-#c]

Experimente online!

No modo aritmético, #nameobtém o código de caractere do primeiro caractere name. Definimos co último caractere e calculamos a diferença entre o primeiro e o último código.



0

Haskell, 61 bytes

import Data.Char
f s=sum$g$ord<$>s
g(a:b:r)=b-a:g(b:r)
g _=[]

0

Java 7, 100 96 bytes

int c(String s){char[]a=s.toCharArray();int r=0,i=a.length-1;for(;i>0;r+=a[i]-a[--i]);return r;}

Ungolfed & código de teste:

Experimente aqui.

class M{
  static int c(String s){
    char[] a = s.toCharArray();
    int r = 0,
        i = a.length-1;
    for(; i > 0; r += a[i] - a[--i]);
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("Hello World!"));
  }
}

Resultado: -39


0

Clojure, 31 bytes

#(-(int(last %))(int(first %)))

Alguém já reduziu a tarefa a uma única operação.

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.