Wyprowadza skumulowane nachylenie łańcucha

12

Wyzwanie

Biorąc pod uwagę ciąg takich jak Hello World!, rozbicie go na jego wartości znakowych 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33.

Następnie należy obliczyć różnicę pomiędzy każdą kolejną parą znaków: 29, 7, 0, 3, -79, 55, 24, 3, -6, -8, -67.

Wreszcie, podsumować je i wydrukować wynik końcowy: -39.

Zasady

  • Obowiązują standardowe luki
  • Brak korzystania z gotowych funkcji wykonujących dokładnie to zadanie
  • Zachęca się do kreatywnych rozwiązań
  • baw się dobrze
  • Jest to oznaczone jako , najkrótsza odpowiedź w bajtach wygrywa, ale nie zostanie wybrana.
dkudriavtsev
źródło
16
Obserwacja Dennisa pokazuje, że zadanie to jest sformułowane w bardziej skomplikowany sposób niż to konieczne.
Greg Martin
Czy język może akceptować wprowadzanie jako tablicę znaków, nawet jeśli obsługuje typy ciągów?
Poke
@Poke przepraszam, musi być sznurkiem
dkudriavtsev
@GregMartin Właściwie dopiero zdałem sobie z tego sprawę. Wyzwanie powinno jednak pozostać.
dkudriavtsev
@DJMcMayhem Dobrze wiedzieć, wszystkie inne formy produkcji są niniejszym dozwolone.
dkudriavtsev

Odpowiedzi:

38

Python, 29 bajtów

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

Suma różnic tworzy szereg teleskopowy, więc większość sum anuluje się i
(s 1 - s 0 ) + (s 2 - s 1 ) +… + (s n-1 - s n-2 ) + (s n - s n-1 ) = s n - s 0 .

Jeśli pobieranie ciągu bajtów jako danych wejściowych jest dozwolone

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

będzie działać również dla 19 bajtów .

Przetestuj oba na Ideone .

Dennis
źródło
Czy to drukuje wynik?
dkudriavtsev
4
Chyba w REPL. Zamierzoną formą wyjścia jest jednak wartość zwracana, która jest jedną z naszych domyślnych metod wyświetlania. Jeśli nie jest to dozwolone, większość odpowiedzi w językach produkcyjnych jest nieprawidłowa.
Dennis
22

MATL , 2 bajty

ds

Wypróbuj online!

Wyjaśnienie:

dpobiera różnicę między kolejnymi znakami i ssumuje wynikową tablicę. Następnie wartość na górze stosu jest domyślnie drukowana. Niewiele więcej na ten temat.

Co ciekawe, mimo że Dennis odkrył niesamowity skrót, użycie go w MATL byłoby znacznie dłuższe.

James
źródło
9

Galaretka , 3 bajty

OIS

Wypróbuj online!

Weź wartości Okońcowe znaków ciągu wejściowego, następnie Iczęści tej listy, a następnie Sum tej listy.

Lynn
źródło
Tak, wydrukowanie wyniku (i przede wszystkim pobranie danych) dzieje się domyślnie w Jelly.
Lynn
6

MATLAB, 16 bajtów

@(x)sum(diff(x))

Stwarza anonimową funkcję nazwaną ansktóry można nazwać tak: ans('Hello world!').

Oto demo online w Octave, które wymaga dodatkowego bajtu, +aby jawnie przekonwertować ciąg wejściowy na tablicę numeryczną przed obliczeniem różnicy między elementami

Suever
źródło
4

Python, 63 bajty

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

Ideone to!

Miedź
źródło
3

Cubix , 13 bajtów

Cubix to dwuwymiarowy język owinięty wokół sześcianu.

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

Przetestuj online! Odwzorowuje to na następującą sieć kostek:

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

Gdzie IP (wskaźnik instrukcji) zaczyna się w lewym górnym rogu skrajnie lewej twarzy.

Jak to działa

Po pierwsze, adres IP uderza w lustro, /które przekierowuje go na igórną powierzchnię. Górna powierzchnia jest pętlą, która nieustannie wprowadza kody znaków, aż do osiągnięcia EOF. Gdy dane wejściowe są puste, wynikiem ijest -1; adres IP skręca w lewo od ?, uderzając /w skrajnie prawą twarz i wykonując następujące polecenia:

  • ; - Pop najwyższy element (-1).
  • # - Naciśnij długość stosu.
  • t- Pop najwyższy przedmiot i dostać przedmiot o tym indeksie na stosie. To pociąga za sobą dolny element.
  • - - Odejmować.
  • O - Wyjście jako liczba całkowita.
  • /- Odrzuca adres IP do @, co kończy program.
ETHprodukcje
źródło
3

C #, 22 bajty

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

Pełny kod źródłowy z przypadkiem testowym:

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 # z LINQ, 17 bajtów

Krótsza wersja, wykorzystująca LINQ, dzięki hstde :

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

Konieczny jest jednak dodatkowy import:

using System.Linq;
adrianmp
źródło
2
s=>s.Last()-s[0];byłoby tylko 17 bajtów
hstde
3

Rubinowy, 23 bajty

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

Przypisz do zmiennej like f=->s{s[-1].ord-s[0].ord}i call likef["Hello World!"]

Wykorzystuje obserwację Dennisa na temat serii teleskopów.

dkudriavtsev
źródło
Nie musisz drukować wyniku, tylko zwróć go, aby się go pozbyć $><<.
Jordan
1
Tak, też przeczytałem pytanie. Na szczęście istnieje powszechna zgoda co do definicji „wyjścia” (patrz także: wiele odpowiedzi na tej stronie, które zwracają, a nie drukują wartość). Ale hej, to twój kod.
Jordan
2

siatka, 12 bajtów

idVc~@qVc-o;

Wypróbuj online!

Korzystając z obserwacji Dennisa , możemy skrócić proces iteracyjny do prostszego.

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
źródło
2

Brain-Flak , 51 bajtów

48 bajtów kodu plus trzy bajty dla -aflagi, która umożliwia wejście ASCII (ale wyjście dziesiętne. Jak wygodne.: D)

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

Wypróbuj online!

To trochę trudniejsze niż moja inna odpowiedź, haha. Przejdźmy przez to.

{           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
źródło
2

05AB1E , 3 bajty

Ç¥O

Wypróbuj online!

Wykorzystuje kodowanie CP-1252.

Wyjaśnienie

Ç       Converts input string to ASCII
¥       Compute difference between successive elements
O       Sum the result
Suever
źródło
Ok fajnie. Przepraszam.
dkudriavtsev
2

Brachylog , 7 bajtów

@c$)@[-

Wypróbuj online!

Wyjaśnienie

@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

Ponieważ odejmowanie działa tylko dla wejścia dwóch liczb całkowitych, odniesie sukces, gdy wybrany zostanie prefiks [33, 72].

Fatalizować
źródło
2

Haskell, 32 bajty

g=fromEnum
f t=g(last t)-g(t!!0)
Damien
źródło
@nimi Jest tak samo.
xnor
2

R, 69 43 32 bajty

Bardzo niekonkurencyjna odpowiedź, chociaż pomyślałem, że fajnie byłoby zaprezentować możliwe rozwiązanie w R.

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

Jedynym interesującym aspektem tej odpowiedzi jest użycie sapplyi charToRaw. Najpierw podzielę ciąg na wektor znaków, który chcę przekonwertować na reprezentacje liczb całkowitych ASCII. charToRawFunkcja jest wektorowy w R i zamiast pętli na każdej wartości powyżej wektora I użytku sapply, które skutecznie vectorizes funkcję. Następnie weź 1. różnicę, a następnie zsumuj.


Edycja: Okazuje się, że charToRawprzekształca ciąg znaków w wektor, w którym każdy element jest surową reprezentacją każdego znaku, stąd nie ma potrzeby używania strsplitisapply

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

Edit2: okazuje się, że jest jeszcze lepszy sposób, funkcja utf8ToInt(x)robi dokładnie to, co strtoi(charToRaw(x),16)dzięki czemu możemy zaoszczędzić kilka więcej bajtów (Idea pochodzi użytkownika @ rturnbull odpowiedź na inne pytanie):

sum(diff(utf8ToInt(readline())))
Billywob
źródło
2

Perl, 19 bajtów

Obejmuje +1 dla -p

Podaj dane wejściowe STDIN bez ostatniej nowej linii

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

slope.pl:

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

Jeśli masz pewność, że łańcuch wejściowy ma co najmniej 2 znaki, ta 17-bajtowa wersja również działa:

#!/usr/bin/perl -p
$_=ord(chop)-ord
Ton Hospel
źródło
2

NodeJS, 82 bajty

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

Wyjaśnienie:

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 bajtów

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}

Taki sam pomysł, jak powyżej, z wejściem funkcji zamiast argumentu.

Alexis_A
źródło
Przepraszamy, ale nie możesz założyć, że xto dane wejściowe. Musisz uzyskać dane wejściowe.
Rɪᴋᴇʀ
Czy to działa w ten sposób?
Alexis_A,
Tak, to działa świetnie!
Rɪᴋᴇʀ
1
Innym dopuszczalnym sposobem uzyskania danych wejściowych jest utworzenie funkcji. Na przykład, f=x=>{...;return t}aby zapisać 2 bajty;)
joeytwiddle
2

JavaScript ES6, 42 39 bajtów

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

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

Wykorzystując obserwację @Dennis na temat sum teleskopu.

Myślę, że w tym przypadku trywialne rozwiązanie jest najkrótsze.

Zaoszczędzono 3 bajty, pozbywając się charCodeAtpowtórzeń, jak sugeruje @Neil.

Lmis
źródło
Najlepsze, co mogłem zrobić s=>s.slice(-1).charCodeAt()-s.charCodeAt(), to ta sama długość.
Neil,
W rzeczywistości charCodeAtjest dość długi, prawdopodobnie istnieje sposób na zaoszczędzenie bajtów poprzez unikanie powtórzeń.
Neil
@Neil Dzięki za sugestię, która pozwoliła mi zaoszczędzić 3 bajty.
Lmis,
Nieco rekurencyjne podejście jest kilka bajtów dłuższe:f=s=>(s[1]?-f(s.slice(-1)):0)-s.charCodeAt()
ETHprodukcje
2

Dalej, 28 bajtów

: f depth 1- roll swap - . ;

Pobiera listę znaków ze stosu (standardowa metoda pobierania parametrów przez Fortha). Znaki są pobierane w taki sposób, że góra stosu jest pierwszym znakiem ciągu. Przesuwam dół stosu na górę, zamieniam, a następnie odejmuję i drukuję. Śmieci zostają na stosie, a dane wyjściowe są drukowane na standardowym wyjściu.

Gdyby każdy znak był wypychany na stos w kolejności zamiast w odwrotnej kolejności, program byłby o 2 bajty krótszy. Nie jestem jednak pewien, czy jest to dozwolone, ponieważ zwykle wypychasz argumenty w odwrotnej kolejności.

Wypróbuj online

Nazywany tak:

33 100 108 114 111 87 32 111 108 108 101 72 f
mbomb007
źródło
2

Java, 42

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

Nie golfowany:

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

Wyjaśnienie:

Działa to na tej samej zasadzie co teleskopowanie:

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

Uogólniona dla dowolnej sekwencji znaków długości n, odpowiedź jest taka, c[n-1] - c[0]że wszystkie elementy w środku są anulowane.


źródło
2

PHP 7.1, 33 31 bajtów

Wykorzystuje ujemne przesunięcia ciągów zaimplementowane w PHP 7.1.

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

Uruchom tak:

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

Poprawki

  • Zaoszczędzono 2 bajty $argn
aross
źródło
1

RProgN , 142 bajtów, niekonkurujący

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

Niekonkurencyjny, ponieważ po odkryciu tego wyzwania dodano komendę „tostack” (mimo że ma straszną liczbę bajtów)

Przypadki testowe

Hello, World!
-39

Cool, huh?
-4

Wyjaśnienie

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 to ezoteryczny język, nad którym pracowałem z myślą o odwrotnej notacji polskiej. Obecnie jest dość gadatliwy, a zmienne przypisanie ma 4 znaki, ale planuję dodać w przyszłości trochę cukru syntaktycznego.

Ponadto RProgN domyślnie uzyskuje dostęp do argumentów ze stosu i zwraca je w ten sam sposób. Wszelkie dane łańcuchowe pozostawione na stosie po zakończeniu programu są domyślnie drukowane.

ATaco
źródło
„Trochę cukru” naprawdę zmieniło formę w ciągu kilku miesięcy. Cała ta sprawa jest teraz ~{bid☼[+i to trochę urocze.
ATaco
1

PHP, 36 bajtów

<?=ord(strrev($s=$argv[1]))-ord($s);
  • Każda postać oprócz pierwszej i ostatniej jest dodawana i odejmowana raz.
    → suma różnic == różnica między pierwszym i ostatnim znakiem
  • ord()w PHP działa na pierwszym znaku ciągu
    → nie ma potrzeby jawnego zmniejszania go do jednego znaku
Tytus
źródło
1

Brain-Flak , 34 32 + 3 = 35 bajtów

+3 z powodu -aflagi wymaganej w trybie ascii.

Wypróbuj online

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

O dziwo, bardziej efektywne jest użycie definicji użytej w specyfikacjach niż „sztuczka” polegająca na odejmowaniu najpierw od ostatniego.

Działa to poprzez wykonanie dokładnie tego.

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

CJam , 8 5 bajtów

Ogromne podziękowania dla Dennisa za dwie sugestie, które usunęły 3 bajty

l)\c-

Wypróbuj online!

Wyjaśnienie

Oblicza ostatnią wartość minus pierwsza wartość.

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
źródło
Jeśli używasz )zamiast W=, nie potrzebujesz _. Również cjako skrót do 0=.
Dennis
@Dennis Wielkie dzięki!
Luis Mendo,
1

Haskell, 36 bajtów

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

stosowanie:

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


Haskell (Lambdabot), 31 bajtów

sum.(tail>>=zipWith(-)).map ord
Gajówka
źródło
Obawiam się, że to nie jest właściwa funkcja. To tylko fragment. sum.(tail>>=zipWith(-)).map fromEnumna przykład jest funkcją.
nimi
@nimi Pytanie nie wymagało prawidłowej funkcji
BlackCap
Pytanie nie zadawało nic, więc domyślnie wskakują, które są pełnymi programami lub funkcjami, ale nie fragmentami .
nimi
1

Zsh , 22 bajty

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

Wypróbuj online!

W trybie arytmetycznym #namepobiera kod pierwszego znaku w name. Ustawiamy cna ostatni znak i uwzględniamy różnicę między pierwszym a ostatnim kodem.

Funkcja Gamma
źródło
0

Haskell, 61 bajtów

import Data.Char
f s=sum$g$ord<$>s
g(a:b:r)=b-a:g(b:r)
g _=[]
joeytwiddle
źródło
0

Java 7, 100 96 bajtów

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

Kod niepoznany i testowy:

Wypróbuj tutaj.

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

Wynik: -39

Kevin Cruijssen
źródło
0

Clojure, 31 bajtów

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

Ktoś zredukował to zadanie do jednej operacji.

Michael M.
źródło