Salida de la pendiente acumulativa de una cadena

12

Desafío

Dada una cadena tales como Hello World!, descomponerlo en sus valores de caracteres: 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33.

A continuación, se calcula la diferencia entre cada par consecutivo de caracteres: 29, 7, 0, 3, -79, 55, 24, 3, -6, -8, -67.

Por último, sumarlos e imprimir el resultado final: -39.

Reglas

  • Se aplican lagunas estándar
  • No usar funciones prefabricadas que realicen esta tarea exacta
  • Soluciones creativas alentadas
  • Que te diviertas
  • Esto está marcado como , la respuesta más corta en bytes gana pero no se seleccionará.
dkudriavtsev
fuente
16
La observación de Dennis muestra que esta tarea está redactada de una manera más complicada de lo necesario.
Greg Martin
¿Puede un idioma aceptar la entrada como una matriz de caracteres incluso si admite tipos de cadena?
Poke
@Poke lo siento, tiene que ser una cadena
dkudriavtsev
@ GregMartin En realidad no me di cuenta de eso hasta más tarde. Sin embargo, el desafío debería seguir así.
dkudriavtsev
@DJMcMayhem Es bueno saber que se permiten todas las demás formas de salida.
dkudriavtsev

Respuestas:

38

Python, 29 bytes

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

La suma de las diferencias forma una serie telescópica, por lo que la mayoría de los sumandos se cancelan y
(s 1 - s 0 ) + (s 2 - s 1 ) +… + (s n-1 - s n-2 ) + (s n - s n-1 ) = s n - s 0 .

Si tomar una cadena de bytes como entrada está permitida

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

funcionará también para 19 bytes .

Prueba ambos en Ideone .

Dennis
fuente
¿Imprime esto el resultado?
dkudriavtsev
44
En un REPL, supongo que sí. Sin embargo, la forma prevista de salida es un valor de retorno, que es uno de nuestros métodos de salida predeterminados. Si eso no está permitido, la mayoría de las respuestas en los idiomas de producción no son válidas.
Dennis
22

MATL , 2 bytes

ds

Pruébalo en línea!

Explicación:

dobtiene la diferencia entre caracteres consecutivos y ssuma la matriz resultante. Luego, el valor en la parte superior de la pila se imprime implícitamente. No hay mucho más que decir al respecto.

Curiosamente, a pesar de que Dennis descubrió un atajo increíble, usarlo sería significativamente más largo en MATL.

James
fuente
9

Jalea , 3 bytes

OIS

Pruébalo en línea!

Tome los Ordinales de los caracteres de la cadena de entrada, luego los Ielementos de esa lista, luego el Sum de esa lista.

Lynn
fuente
Sí, imprimir el resultado (y tomar la entrada en primer lugar) sucede implícitamente en Jelly.
Lynn
6

MATLAB, 16 bytes

@(x)sum(diff(x))

Esto crea una función anónima llamada ansque puede ser llamado como: ans('Hello world!').

Aquí hay una demostración en línea en Octave que requiere un byte adicional +para convertir explícitamente la cadena de entrada en una matriz numérica antes de calcular la diferencia de elemento a elemento

Suever
fuente
4

Python, 63 bytes

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

Ideone it!

Cobre
fuente
3

Cubix , 13 bytes

Cubix es un lenguaje bidimensional envuelto alrededor de un cubo.

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

¡Pruébalo en línea! Esto se asigna a la siguiente red de cubos:

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

Donde el IP (puntero de instrucción) comienza en la parte superior izquierda de la cara del extremo izquierdo.

Cómo funciona

Primero, la IP golpea el espejo /que lo redirige a la icara superior. La cara superior es un bucle que ingresa continuamente códigos de caracteres hasta que se alcanza EOF. Cuando la entrada está vacía, el resultado ies -1; el IP gira a la izquierda desde el ?, golpeando /el extremo derecho y pasando por los siguientes comandos:

  • ; - Pop el elemento superior (-1).
  • # - Empuje la longitud de la pila.
  • t- Pop el elemento superior y obtener el elemento en ese índice en la pila. Esto levanta el elemento inferior.
  • - - Restar
  • O - Salida como un entero.
  • /- Desvía la IP hacia @, que finaliza el programa.
ETHproductions
fuente
3

C #, 22 bytes

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

Código fuente completo con caso de prueba:

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 # con LINQ, 17 bytes

Una versión más corta, usando LINQ, gracias a hstde :

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

Sin embargo, es necesaria una importación adicional:

using System.Linq;
adrianmp
fuente
2
s=>s.Last()-s[0];sería solo 17 bytes
hstde
3

Ruby, 23 bytes

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

Asignar a una variable como f=->s{s[-1].ord-s[0].ord}y llamar comof["Hello World!"]

Utiliza la observación de Dennis sobre series telescópicas.

dkudriavtsev
fuente
No necesita imprimir el resultado, solo devolverlo, para que pueda deshacerse de él $><<.
Jordan
1
Sí, también leí la pregunta. Afortunadamente, existe un amplio consenso sobre la definición de "salida" (ver también: las muchas respuestas en esta página que devuelven en lugar de imprimir un valor). Pero bueno, es tu código.
Jordania
2

reticular, 12 bytes

idVc~@qVc-o;

Pruébalo en línea!

Usando la observación de Dennis , podemos acortar un proceso iterativo en uno más simple.

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
Conor O'Brien
fuente
2

Brain-Flak , 51 bytes

48 bytes de código más tres bytes para el -aindicador, que permite la entrada ASCII (pero la salida decimal. Qué conveniente.: D)

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

Pruébalo en línea!

Estas son un poco más difíciles que mi otra respuesta, jaja. Pasemos por él.

{           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
James
fuente
2

05AB1E , 3 bytes

Ç¥O

Pruébalo en línea!

Utiliza la codificación CP-1252.

Explicación

Ç       Converts input string to ASCII
¥       Compute difference between successive elements
O       Sum the result
Suever
fuente
Está bien. Lo siento.
dkudriavtsev
2

Brachylog , 7 bytes

@c$)@[-

Pruébalo en línea!

Explicación

@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 restar solo funciona para una entrada de dos enteros, tendrá éxito una vez que el prefijo seleccionado sea [33, 72].

Fatalizar
fuente
2

Haskell, 32 bytes

g=fromEnum
f t=g(last t)-g(t!!0)
Damien
fuente
@nimi Es lo mismo.
xnor
2

R, 69 43 32 bytes

Una respuesta muy poco competitiva, aunque pensé que sería divertido mostrar una posible solución en R.

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

El único aspecto interesante de esta respuesta es el uso de sapplyy charToRaw. Primero dividí la cadena en un vector de caracteres que quiero convertir en sus representaciones enteras ASCII. La charToRawfunción no está vectorizada en R y en lugar de recorrer cada valor en el vector antes mencionado que uso, sapplyque efectivamente vectoriza la función. Posteriormente tome la primera diferencia y luego la suma.


Editar: resulta charToRawtransformar una cadena en un vector donde cada elemento es la representación en bruto de cada carácter, por lo tanto, no es necesario usar strsplitysapply

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

Edit2: Resulta que hay una forma aún mejor, la función utf8ToInt(x)hace exactamente lo strtoi(charToRaw(x),16)que significa que podemos guardar algunos bytes más (Idea tomada de la respuesta de @ rturnbull a otra pregunta):

sum(diff(utf8ToInt(readline())))
Billywob
fuente
2

Perl, 19 bytes

Incluye +1 para -p

Dar entrada en STDIN sin nueva línea final

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

slope.pl:

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

Si está seguro de que la cadena de entrada tiene al menos 2 caracteres, esta versión de 17 bytes también funciona:

#!/usr/bin/perl -p
$_=ord(chop)-ord
Ton Hospel
fuente
2

NodoJS, 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

Explicación:

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}

La misma idea que la anterior con una entrada de función en lugar de un argumento.

Alexis_A
fuente
Lo sentimos, pero no puedes asumir que xes la entrada. Necesitas realmente obtener información.
Rɪᴋᴇʀ
¿Funciona así?
Alexis_A
Sí, eso funciona muy bien!
Rɪᴋᴇʀ
1
Otra forma aceptable de obtener información es crear una función. Por ejemplo, f=x=>{...;return t}para guardar 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 la observación de @Dennis sobre sumas de telescopios.

Creo que en este caso la solución trivial es la más corta.

Ahorró 3 bytes al deshacerse de la charCodeAtrepetición como lo sugiere @Neil.

Lmis
fuente
Lo mejor que pude hacer fue s=>s.slice(-1).charCodeAt()-s.charCodeAt()que resulta ser de la misma longitud.
Neil
En realidad charCodeAtes bastante largo, probablemente haya una forma de guardar bytes evitando la repetición.
Neil
@Neil Gracias por la sugerencia, que me ahorró 3 bytes.
Lmis
Un enfoque ligeramente recursivo es unos pocos bytes más largos:f=s=>(s[1]?-f(s.slice(-1)):0)-s.charCodeAt()
ETHproductions
2

Adelante, 28 bytes

: f depth 1- roll swap - . ;

Toma una lista de caracteres en la pila (el método estándar de Forth para tomar parámetros). Los caracteres se toman de tal manera que la parte superior de la pila es el primer carácter de la cadena. Muevo la parte inferior de la pila a la parte superior, cambio, luego resta e imprimo. Se deja basura en la pila y la salida se imprime en stdout.

Si cada carácter fuera empujado a la pila en orden en lugar de en orden inverso, el programa sería 2 bytes más corto. Sin embargo, no estoy seguro de si eso está permitido, porque normalmente empujas los argumentos en orden inverso.

Pruébalo en línea

Llamado así:

33 100 108 114 111 87 32 111 108 108 101 72 f
mbomb007
fuente
2

Java, 42

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

Sin golf:

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

Explicación:

Esto utiliza el mismo principio que el telescopio:

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

Generalizado para cualquier secuencia de caracteres de longitud n, la respuesta es c[n-1] - c[0]porque todas las cosas en el medio se cancelan.


fuente
2

PHP 7.1, 33 31 bytes

Utiliza compensaciones de cadena negativas implementadas en PHP 7.1.

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

Corre así:

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

Ajustes

  • Guardado 2 bytes usando $argn
aross
fuente
1

RProgN , 142 Bytes, No competidor

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

No compite, ya que el comando 'tostack' se agregó después del descubrimiento de este desafío (a pesar de que tiene un recuento de bytes terrible)

Casos de prueba

Hello, World!
-39

Cool, huh?
-4

Explicación

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 es un lenguaje esotérico en el que he estado trabajando teniendo en cuenta la notación polaca inversa. Actualmente es bastante detallado, con una asignación variable de 4 caracteres y, sin embargo, planeo agregar en el futuro un poco de azúcar sintética.

Además, RProgN accede implícitamente a los argumentos de la pila y los devuelve de la misma manera. Cualquier dato de cadena que quede en la pila después de que el programa haya finalizado, se imprime implícitamente.

Un taco
fuente
"Un poco de azúcar" realmente cambió de forma en los pocos meses que esto tomó. Todo esto es ahora ~{bid☼[+y eso es un poco adorable.
ATaco
1

PHP, 36 bytes

<?=ord(strrev($s=$argv[1]))-ord($s);
  • Todos los personajes, excepto el primero y el último, se suman y restan una vez cada uno.
    → suma de diferencias == diferencia entre el primer y el último carácter
  • ord()en PHP opera en el primer carácter de una cadena
    → no es necesario reducirlo explícitamente a un solo carácter
Titus
fuente
1

Brain-Flak , 34 32 + 3 = 35 bytes

+3 debido a la -abandera requerida para el modo ASCII.

Pruébalo en línea

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

Curiosamente, es más eficiente usar la definición utilizada en las especificaciones en lugar del "truco" de restar primero de último.

Esto funciona haciendo exactamente eso.

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

CJam , 8 5 bytes

Muchas gracias a Dennis por dos sugerencias que eliminaron 3 bytes

l)\c-

Pruébalo en línea!

Explicación

Calcula el último valor menos el primer 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
Luis Mendo
fuente
Si usa en )lugar de W=, no necesita el _. Además, ccomo atajo para 0=.
Dennis
@ Dennis Muchas gracias!
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
Alondra
fuente
Me temo que esta no es una función adecuada. Es solo un fragmento. sum.(tail>>=zipWith(-)).map fromEnumPor ejemplo es una función.
nimi
@nimi La pregunta no pedía una función adecuada
BlackCap
La pregunta no pedía nada, por lo que entran en juego los valores predeterminados, que son programas o funciones completos, pero no fragmentos .
nimi
1

Zsh , 22 bytes

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

Pruébalo en línea!

En modo aritmético, #nameobtiene el código de carácter del primer carácter name. Establecemos cel último carácter y tomamos la diferencia entre el primer y el último código.

Función Gamma
fuente
0

Haskell, 61 bytes

import Data.Char
f s=sum$g$ord<$>s
g(a:b:r)=b-a:g(b:r)
g _=[]
joeytwiddle
fuente
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 y código de prueba:

Pruébalo aquí.

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!"));
  }
}

Salida: -39

Kevin Cruijssen
fuente
0

Clojure, 31 bytes

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

Alguien redujo la tarea a una sola operación.

Michael M
fuente