12
\$\begingroup\$

Challenge

Given a string such as Hello World!, break it down into its character values: 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33.

Then calculate the difference between each consecutive pair of characters: 29, 7, 0, 3, -79, 55, 24, 3, -6, -8, -67.

Finally, sum them and print the final result: -39.

Rules

  • Standard loopholes apply
  • No using pre-made functions that perform this exact task
  • Creative solutions encouraged
  • Have fun
  • This is marked as , the shortest answer in bytes wins but will not be selected.
\$\endgroup\$
  • 14
    \$\begingroup\$ Dennis's observation shows that this task is phrased in a more complicated way than necessary. \$\endgroup\$ – Greg Martin Sep 26 '16 at 2:47
  • \$\begingroup\$ Can a language accept input as a character array even if it supports string types? \$\endgroup\$ – Poke Sep 26 '16 at 15:13
  • \$\begingroup\$ @Poke sorry, has to be a string \$\endgroup\$ – dkudriavtsev Sep 27 '16 at 20:19
  • \$\begingroup\$ @GregMartin I actually did not realize that until later. The challenge should stay this way though. \$\endgroup\$ – dkudriavtsev Sep 27 '16 at 20:19
  • \$\begingroup\$ @DJMcMayhem Good to know, all other forms of output are hereby allowed. \$\endgroup\$ – dkudriavtsev Sep 27 '16 at 20:58

37 Answers 37

37
\$\begingroup\$

Python, 29 bytes

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

The sum of the differences forms a telescopic series, so most summands cancel out and
(s1 - s0) + (s2 - s1) + … + (sn-1 - sn-2) + (sn - sn-1) = sn - s0.

If taking a byte string as input is allowed

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

will work as well for 19 bytes.

Test both on Ideone.

\$\endgroup\$
  • \$\begingroup\$ Does this print the result? \$\endgroup\$ – dkudriavtsev Sep 27 '16 at 20:10
  • 2
    \$\begingroup\$ In a REPL, I guess it does. The intended form of output is a return value though, which is one of our default methods of output. If that's not allowed, most of the answers in production languages are invalid. \$\endgroup\$ – Dennis Sep 27 '16 at 20:30
19
\$\begingroup\$

MATL, 2 bytes

ds

Try it online!

Explanation:

d gets the difference between consecutive characters and s sums the resulting array. Then, the value on top of the stack is implicitly printed. Not much else to say about that.

Interestingly enough, even though Dennis discovered an awesome shortcut, using it would be significantly longer in MATL.

\$\endgroup\$
  • \$\begingroup\$ @DmitryKudriavtsev Yes, the stack is implicitly printed in MATL. Why not try it? That's why I provided a link to an online interpreter. \$\endgroup\$ – DJMcMayhem Sep 27 '16 at 20:10
8
\$\begingroup\$

Jelly, 3 bytes

OIS

Try it online!

Take the Ordinals of the input string’s characters, then the Increments of that list, then the Sum of that list.

\$\endgroup\$
  • \$\begingroup\$ Yeah, printing the result (and taking input in the first place) happens implicitly in Jelly. \$\endgroup\$ – Lynn Sep 27 '16 at 20:11
6
\$\begingroup\$

MATLAB, 16 bytes

@(x)sum(diff(x))

This creates an anonymous function named ans which can be called like: ans('Hello world!').

Here is an online demo in Octave which requires an additional byte + to explicitly convert the input string to a numeric array prior to computing the element-to-element difference

\$\endgroup\$
4
\$\begingroup\$

Python, 63 bytes

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

Ideone it!

\$\endgroup\$
3
\$\begingroup\$

Cubix, 13 bytes

Cubix is a 2-dimensional language wrapped around a cube.

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

Test it online! This maps to the following cube net:

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

Where the IP (instruction pointer) starts at the top-left of the far-left face.

How it works

First, the IP hits the mirror / which redirects it onto the i on the top face. The top face is a loop which continually inputs charcodes until EOF is reached. When the input is empty, the result of i is -1; the IP turns left from the ?, hitting the / on the far right face and going through the following commands:

  • ; - Pop the top item (-1).
  • # - Push the length of the stack.
  • t - Pop the top item and get the item at that index in the stack. This pulls up the bottom item.
  • - - Subtract.
  • O - Output as an integer.
  • / - Deflects the IP to the @, which ends the program.
\$\endgroup\$
3
\$\begingroup\$

C#, 22 bytes

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

Full source code with test case:

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

A shorter version, using LINQ, thanks to hstde:

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

However, an extra import is necessary:

using System.Linq;
\$\endgroup\$
  • 2
    \$\begingroup\$ s=>s.Last()-s[0]; would be only 17 bytes \$\endgroup\$ – hstde Sep 27 '16 at 6:06
3
\$\begingroup\$

Ruby, 23 bytes

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

Assign to a variable like f=->s{s[-1].ord-s[0].ord} and call like f["Hello World!"]

Uses Dennis's observation about telescopic series.

\$\endgroup\$
  • \$\begingroup\$ You don't need to print the output, only return it, so you can get rid of $><<. \$\endgroup\$ – Jordan Sep 26 '16 at 5:52
  • 1
    \$\begingroup\$ Yes, I read the question also. Luckily, there is broad consensus on the definition of "output" (see also: the many answers on this page which return rather than print a value). But hey, it's your code. \$\endgroup\$ – Jordan Sep 27 '16 at 20:04
2
\$\begingroup\$

reticular, 12 bytes

idVc~@qVc-o;

Try it online!

Using Dennis's observation, we can shorten an iterative process into a simpler one.

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
\$\endgroup\$
2
\$\begingroup\$

Brain-Flak, 51 bytes

48 bytes of code plus three bytes for the -a flag, which enables ASCII input (but decimal output. How convenient. :D)

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

Try it online!

This ones a little bit harder than my other answer, haha. Lets walk through it.

{           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
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 3 bytes

Ç¥O

Try it Online!

Uses CP-1252 encoding.

Explanation

Ç       Converts input string to ASCII
¥       Compute difference between successive elements
O       Sum the result
\$\endgroup\$
  • \$\begingroup\$ OK, cool. Sorry. \$\endgroup\$ – dkudriavtsev Sep 27 '16 at 20:14
2
\$\begingroup\$

Haskell, 32 bytes

g=fromEnum
f t=g(last t)-g(t!!0)
\$\endgroup\$
  • \$\begingroup\$ @nimi It's the same. \$\endgroup\$ – xnor Sep 27 '16 at 7:06
2
\$\begingroup\$

Perl, 19 bytes

Includes +1 for -p

Give input on STDIN without final newline

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

slope.pl:

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

If you are sure the input string has at least 2 characters this 17 byte version works too:

#!/usr/bin/perl -p
$_=ord(chop)-ord
\$\endgroup\$
2
\$\begingroup\$

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

Explanation:

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}

Same idea as above with a function input instead of an argument.

\$\endgroup\$
  • \$\begingroup\$ Sorry, but you can't assume x is the input. You need to actually get input. \$\endgroup\$ – Rɪᴋᴇʀ Sep 26 '16 at 2:22
  • \$\begingroup\$ Does that work this way ? \$\endgroup\$ – Alexis_A Sep 26 '16 at 2:37
  • \$\begingroup\$ Yes, that works great! \$\endgroup\$ – Rɪᴋᴇʀ Sep 26 '16 at 2:42
  • 1
    \$\begingroup\$ Another acceptable way to get input is to create a function. For example f=x=>{...;return t} to save 2 bytes ;) \$\endgroup\$ – joeytwiddle Sep 26 '16 at 6:30
2
\$\begingroup\$

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

Using @Dennis observation about telescope sums.

I think in this case the trivial solution is the shortest.

Saved 3 bytes by getting rid of th the charCodeAt repetition as suggested by @Neil.

\$\endgroup\$
  • \$\begingroup\$ Best I could do was s=>s.slice(-1).charCodeAt()-s.charCodeAt() which turns out to be the same length. \$\endgroup\$ – Neil Sep 26 '16 at 13:30
  • \$\begingroup\$ Actually charCodeAt is quite long, there's probably a way to save bytes by avoiding the repetition. \$\endgroup\$ – Neil Sep 26 '16 at 13:31
  • \$\begingroup\$ @Neil Thanks for the suggestion, that saved me 3 bytes. \$\endgroup\$ – Lmis Sep 26 '16 at 13:45
  • \$\begingroup\$ A slightly recursive approach is a few bytes longer: f=s=>(s[1]?-f(s.slice(-1)):0)-s.charCodeAt() \$\endgroup\$ – ETHproductions Sep 26 '16 at 15:19
2
\$\begingroup\$

PHP 7.1, 33 31 bytes

Uses negative string offsets implemented in PHP 7.1.

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

Run like this:

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

Tweaks

  • Saved 2 bytes by using $argn
\$\endgroup\$
1
\$\begingroup\$

RProgN, 142 Bytes, Non-competing

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

Non-competing, as the 'tostack' command was added after the discovery of this challenge (even though it has a terrible byte count)

Test Cases

Hello, World!
-39

Cool, huh?
-4

Explanation

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 is an esoteric language I've been working on with Reverse Polish Notation in mind. It's currently pretty verbose, with it's variable assignment being 4 characters, and such, however I plan to in future add a bit of syntatic sugar.

Also, RProgN implicitly accesses arguments from the stack, and returns them the same way. Any string data left in the stack after the program has finished, is implicitly printed.

\$\endgroup\$
  • \$\begingroup\$ "A bit of Sugar" really changed form in the few months this took. This entire thing is now ~{bid☼[+ and that's a bit adorable. \$\endgroup\$ – ATaco Dec 6 '16 at 0:40
1
\$\begingroup\$

Brachylog, 7 bytes

@c$)@[-

Try it online!

Explanation

@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

Since subtract only works for an input of two integers, it will succeed once the selected prefix is [33, 72].

\$\endgroup\$
1
\$\begingroup\$

R, 69 43 32 bytes

A very non-competing answer although I thought it'd be fun to showcase a possible solution in R.

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

The only interesting aspect of this answer is the use of sapplyand charToRaw. First I split the string into a vector of characters that I want to convert into its ASCII integer representations. The charToRaw function is not vectorized in R and instead of looping over each value in aforementioned vector I use sapply which effectively vectorizes the function. Subsequently take 1st difference and then sum.


Edit: Turns out charToRaw transform a string into a vector where each element is the raw representation of each character, hence no need to use strsplit and sapply

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

Edit2: Turns out there is an even better way, the function utf8ToInt(x) does exactly what strtoi(charToRaw(x),16) which means we can save a few more bytes (Idea taken from @rturnbull's answer to another question):

sum(diff(utf8ToInt(readline())))
\$\endgroup\$
1
\$\begingroup\$

PHP, 36 bytes

<?=ord(strrev($s=$argv[1]))-ord($s);
  • Every character but the first and the last are added and substracted once each.
    → sum of differences == difference between first and last character
  • ord() in PHP operates on the first character of a string
    → no need to explicitly reduce it to a single character
\$\endgroup\$
1
\$\begingroup\$

Forth, 28 bytes

: f depth 1- roll swap - . ;

Takes a list of characters on the stack (Forth's standard method of taking parameters.) The characters are taken such that the top of the stack is the first character of the string. I move the bottom of the stack to the top, swap, then subtract and print. Garbage is left on the stack, and output is printed to stdout.

If each character were pushed to the stack in order instead of reverse order, the program would be 2 bytes shorter. Not sure if that's allowed, though, because normally you push arguments in reverse order.

Try it online

Called like this:

33 100 108 114 111 87 32 111 108 108 101 72 f
\$\endgroup\$
1
\$\begingroup\$

Brain-Flak, 34 32 + 3 = 35 bytes

+3 because of the -a flag required for ascii mode.

Try it online

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

Strangely it is more efficient to actually use the definition used in the specs rather than the "trick" of subtracting first from last.

This works by doing exactly that.

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

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];
  }

Explanation:

This uses the same principle as telescoping:

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

Generalized for any sequence of characters of length n, the answer is c[n-1] - c[0] because all the stuff in the middle cancels out.

\$\endgroup\$
1
\$\begingroup\$

CJam, 8 5 bytes

Big thanks to Dennis for two suggestions that removed 3 bytes

l)\c-

Try it online!

Explanation

Computes last value minus first value.

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
\$\endgroup\$
  • \$\begingroup\$ If you use ) instead of W=, you don't need the _. Also, c as a shortcut for 0=. \$\endgroup\$ – Dennis Sep 26 '16 at 21:23
  • \$\begingroup\$ @Dennis Thanks a lot! \$\endgroup\$ – Luis Mendo Sep 26 '16 at 22:05
1
\$\begingroup\$

Haskell, 36 bytes

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

usage:

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


Haskell (Lambdabot), 31 bytes

sum.(tail>>=zipWith(-)).map ord
\$\endgroup\$
  • \$\begingroup\$ I'm afraid this isn't a proper function. It's just a snippet. sum.(tail>>=zipWith(-)).map fromEnum for example is a function. \$\endgroup\$ – nimi Sep 27 '16 at 0:05
  • \$\begingroup\$ @nimi The question didn't ask for a proper function \$\endgroup\$ – BlackCap Sep 27 '16 at 13:07
  • \$\begingroup\$ The question asked for nothing, so the defaults jump in, which are full programs or functions, but not snippets. \$\endgroup\$ – nimi Sep 27 '16 at 15:45
0
\$\begingroup\$

Haskell, 61 bytes

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

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 & test code:

Try it here.

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

Output: -39

\$\endgroup\$
0
\$\begingroup\$

Clojure, 31 bytes

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

Someone reduced the task already to a single operation.

\$\endgroup\$
0
\$\begingroup\$

PHP, 39 Bytes

<?=ord(substr($s=$argv[1],-1))-ord($s);
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 30 bytes

Tr@Differences@ToCharacterCode
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.