Выведите накопительный наклон строки

12

Вызов

Учитывая строку, как показано Hello World!, разбить его на его символьные значения: 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33.

Затем вычислить разность между каждой последовательной парой символов: 29, 7, 0, 3, -79, 55, 24, 3, -6, -8, -67.

И, наконец, подвести их и напечатать конечный результат: -39.

правила

  • Применяются стандартные лазейки
  • Не используйте готовые функции, которые выполняют эту задачу
  • Творческие решения поощряются
  • Веселиться
  • Это помечено как , самый короткий ответ в байтах выигрывает, но не будет выбран.
dkudriavtsev
источник
16
Наблюдение Денниса показывает, что эта задача сформулирована более сложным способом, чем необходимо.
Грег Мартин
Может ли язык принимать ввод как символьный массив, даже если он поддерживает строковые типы?
Тыкнуть
@ Прошу прощения, должна быть строка
dkudriavtsev
@GregMartin Я на самом деле не понял, что до позже. Задача должна оставаться такой же, хотя.
Дкудрявцев
@DJMcMayhem Полезно знать, что разрешены все другие формы вывода.
Дкудрявцев

Ответы:

38

Python, 29 байт

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

Сумма разностей образует телескопический ряд, поэтому большинство слагаемых сокращают и
(s 1 - s 0 ) + (s 2 - s 1 ) +… + (s n-1 - s n-2 ) + (s n - s n-1 ) = s n - s 0 .

Если разрешено использование байтовой строки в качестве входных данных

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

будет работать также на 19 байтов .

Проверьте оба на Ideone .

Деннис
источник
Это печатает результат?
Дкудрявцев
4
В REPL, я думаю, это так. Предполагаемая форма вывода - это возвращаемое значение, которое является одним из наших методов вывода по умолчанию. Если это не разрешено, большинство ответов на рабочих языках являются недействительными.
Деннис
22

MATL , 2 байта

ds

Попробуйте онлайн!

Объяснение:

dполучает разницу между последовательными символами и sсуммирует полученный массив. Затем значение сверху стека печатается неявно. Больше нечего сказать по этому поводу.

Интересно, что даже несмотря на то, что Деннис обнаружил потрясающий ярлык, его использование в MATL будет значительно дольше.

Джеймс
источник
9

Желе , 3 байта

OIS

Попробуйте онлайн!

Возьмите Ordinals символов входной строки, затем Inrrements этого списка, затем Sum этого списка.

Линн
источник
Да, печать результата (и, прежде всего, ввода) происходит в Jelly неявно.
Линн
6

MATLAB, 16 байтов

@(x)sum(diff(x))

Это создает анонимную функцию с именем , ansкоторое можно назвать как: ans('Hello world!').

Вот онлайн-демонстрация в Octave, которая требует дополнительного байта +для явного преобразования входной строки в числовой массив перед вычислением разницы между элементами

Suever
источник
3

Cubix , 13 байт

Cubix - это двумерный язык, обернутый вокруг куба.

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

Проверьте это онлайн! Это соответствует следующей сети кубов:

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

Где IP (указатель инструкции) начинается в верхнем левом углу крайней левой грани.

Как это устроено

Сначала IP попадает в зеркало, /которое перенаправляет его на iверхнюю поверхность. Верхняя грань представляет собой цикл, который непрерывно вводит коды, пока не будет достигнут EOF. Когда вход пуст, результат iравен -1; IP поворачивается влево от ?, нажимая /на крайнее правое лицо и выполняя следующие команды:

  • ; - Поп верхний элемент (-1).
  • # - толкать длину стека.
  • t- Взять верхний элемент и получить элемент по этому индексу в стеке. Это подтягивает нижний предмет.
  • - - вычесть.
  • O - Вывести в виде целого числа.
  • /- Отклоняет IP до того @, на котором заканчивается программа.
ETHproductions
источник
3

C #, 22 байта

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

Полный исходный код с тестовым примером:

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 # с LINQ, 17 байт

Более короткая версия, использующая LINQ, благодаря hstde :

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

Тем не менее, дополнительный импорт необходим:

using System.Linq;
adrianmp
источник
2
s=>s.Last()-s[0];будет только 17 байт
hstde
3

Рубин, 23 байта

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

Присвоить переменную like f=->s{s[-1].ord-s[0].ord}и вызвать likef["Hello World!"]

Использует наблюдения Денниса о телескопических сериях.

dkudriavtsev
источник
Вам не нужно печатать вывод, только вернуть его, чтобы вы могли избавиться от $><<.
Джордан
1
Да, я тоже прочитал вопрос. К счастью, существует широкий консенсус в отношении определения «вывода» (см. Также: множество ответов на этой странице, которые возвращают, а не печатают значение). Но эй, это твой код.
Джордан
2

сетчатый, 12 байтов

idVc~@qVc-o;

Попробуйте онлайн!

Используя наблюдения Денниса , мы можем сократить итерационный процесс до более простого.

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 байт

48 байтов кода плюс три байта для -aфлага, который позволяет ввод ASCII (но десятичный вывод. Насколько удобно.: D)

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

Попробуйте онлайн!

Это немного сложнее, чем мой другой ответ, хаха. Пройдемся по нему.

{           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

05AB1E , 3 байта

Ç¥O

Попробуйте онлайн!

Использует кодировку CP-1252.

объяснение

Ç       Converts input string to ASCII
¥       Compute difference between successive elements
O       Sum the result
Suever
источник
Ладно, круто. Сожалею.
Дкудрявцев
2

Брахилог , 7 байт

@c$)@[-

Попробуйте онлайн!

объяснение

@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

Поскольку вычитание работает только для ввода двух целых чисел, оно выполнится успешно, как только выбран префикс [33, 72].

Fatalize
источник
2

Haskell, 32 байта

g=fromEnum
f t=g(last t)-g(t!!0)
Damien
источник
@nimi Это то же самое.
xnor
2

R 69 43 32 байта

Очень неконкурентный ответ, хотя я думал, что было бы весело продемонстрировать возможное решение в R.

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

Единственный интересный аспект этого ответа - использование sapplyи charToRaw. Сначала я разбил строку на вектор символов, которые я хочу преобразовать в целочисленные представления ASCII. charToRawФункция не векторизована в R и вместо цикла по каждому значению в вышеупомянутом векторе I использовании , sapplyкоторые эффективно векторизацию функции. Затем возьмите 1-ую разницу и затем сумму.


Редактировать: Оказывается, charToRawпреобразовать строку в вектор, где каждый элемент является необработанным представлением каждого символа, следовательно, нет необходимости использовать strsplitиsapply

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

Edit2: Оказывается, есть еще лучший способ, функция utf8ToInt(x)делает именно то, strtoi(charToRaw(x),16)что означает, что мы можем сохранить еще несколько байтов (идея взята из ответа @ rturnbull на другой вопрос):

sum(diff(utf8ToInt(readline())))
Billywob
источник
2

Perl, 19 байт

Включает +1 для -p

Дайте ввод на STDIN без окончательного перевода строки

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

slope.pl:

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

Если вы уверены, что входная строка содержит как минимум 2 символа, эта 17-байтовая версия также работает:

#!/usr/bin/perl -p
$_=ord(chop)-ord
Тон Хоспел
источник
2

NodeJS, 82 байта

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

Объяснение:

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 байт

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}

Та же идея, что и выше, с вводом функции вместо аргумента.

Alexis_A
источник
Извините, но вы не можете предположить, xчто это вход. Вы должны на самом деле получить вход.
Rɪᴋᴇʀ
Это работает так?
Alexis_A
Да, это прекрасно работает!
Rɪᴋᴇʀ
1
Еще один приемлемый способ получить ввод - создать функцию. Например, f=x=>{...;return t}чтобы сохранить 2 байта;)
joeytwiddle
2

JavaScript ES6, 42 39 байт

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

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

Использование @Dennis наблюдения о суммах телескопов.

Я думаю, что в этом случае тривиальное решение является самым коротким.

Сэкономили 3 байта, избавившись от charCodeAtповторения, как предложено @Neil.

LMIS
источник
Лучшее, что я мог сделать, это то, s=>s.slice(-1).charCodeAt()-s.charCodeAt()что оказалось такой же длины.
Нил
На самом деле charCodeAtэто довольно долго, вероятно, есть способ сохранить байты, избегая повторения.
Нил
@Neil Спасибо за предложение, которое спасло меня 3 байта.
Lmis
Немного рекурсивный подход на несколько байт длиннее:f=s=>(s[1]?-f(s.slice(-1)):0)-s.charCodeAt()
ETHproductions
2

Далее 28 байт

: f depth 1- roll swap - . ;

Принимает список символов в стеке (стандартный метод Forth для получения параметров.) Символы берутся так, что верхняя часть стека является первым символом строки. Я перемещаю нижнюю часть стопки вверх, меняю местами, затем вычитаю и печатаю. Мусор остается в стеке, а вывод выводится на стандартный вывод.

Если бы каждый символ помещался в стек по порядку, а не в обратном порядке, программа была бы на 2 байта короче. Не уверен, что это разрешено, потому что обычно вы выдвигаете аргументы в обратном порядке.

Попробуйте онлайн

Вызывается так:

33 100 108 114 111 87 32 111 108 108 101 72 f
mbomb007
источник
2

Ява, 42

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

Ungolfed:

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

Объяснение:

Это использует тот же принцип, что и телескопирование:

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

Обобщенный для любой последовательности символов длины n, ответ состоит в том, c[n-1] - c[0]что все содержимое в середине сокращается.


источник
2

PHP 7.1, 33 31 байт

Использует отрицательные смещения строк, реализованные в PHP 7.1.

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

Запустите так:

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

Tweaks

  • Сохранено 2 байта с помощью $argn
aross
источник
1

RProgN , 142 байта, неконкурентный

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

Неконкурентный, так как команда 'tostack' была добавлена ​​после обнаружения этой проблемы (даже при том, что у нее ужасный счетчик байтов)

Тестовые случаи

Hello, World!
-39

Cool, huh?
-4

объяснение

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 - эзотерический язык, над которым я работаю, имея в виду обратную польскую нотацию. В настоящее время он довольно многословен, с назначением переменной из 4 символов, но я планирую добавить немного синтетического сахара.

Кроме того, RProgN неявно обращается к аргументам из стека и возвращает их таким же образом. Любые строковые данные, оставленные в стеке после завершения программы, печатаются неявно.

Ataco
источник
«Немного сахара» действительно изменил форму за те несколько месяцев, которые потребовались. Все это сейчас, ~{bid☼[+и это немного восхитительно.
ATaco
1

PHP, 36 байт

<?=ord(strrev($s=$argv[1]))-ord($s);
  • Каждый символ, кроме первого и последнего, добавляется и вычитается по одному разу.
    → сумма различий == разница между первым и последним символом
  • ord()в PHP работает с первым символом строки
    → нет необходимости явно сокращать его до одного символа
Titus
источник
1

Brain-Flak , 34 32 + 3 = 35 байт

+3 из-за -a флага, необходимого для режима ascii.

Попробуйте онлайн

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

Странно, но на самом деле более эффективно использовать определение, используемое в спецификациях, а не «хитрость» вычитания первого из последнего.

Это работает именно так.

(                           )  Push
 ([][()]){[{}]...([][()])}     While the stack has more than one item
  [{}]({})                     Subtract the top from a copy of the second
                          <>   Switch
Специальный охотник за гарфами
источник
1

CJam , 8 5 байтов

Большое спасибо Деннису за два предложения, которые удалили 3 байта

l)\c-

Попробуйте онлайн!

объяснение

Вычисляет последнее значение минус первое значение.

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
Луис Мендо
источник
Если вы используете )вместо W=, вам не нужно _. Также cкак ярлык для 0=.
Деннис
@Dennis Большое спасибо!
Луис Мендо
1

Haskell, 36 байт

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

использование:

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


Haskell (Lambdabot), 31 байт

sum.(tail>>=zipWith(-)).map ord
судейская шапочка
источник
Боюсь, это не правильная функция. Это всего лишь фрагмент. sum.(tail>>=zipWith(-)).map fromEnumнапример, это функция.
Ними
@nimi Вопрос не задан для правильной функции
BlackCap
Вопрос напрашивался ни за что, поэтому проскакивают значения по умолчанию, которые представляют собой полные программы или функции, но не фрагменты .
Ними
1

Zsh , 22 байта

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

Попробуйте онлайн!

В арифметическом режиме #nameполучает код символа первого символа в name. Мы устанавливаем cпоследний символ и берем разницу между первым и последним кодами.

GammaFunction
источник
0

Haskell, 61 байт

import Data.Char
f s=sum$g$ord<$>s
g(a:b:r)=b-a:g(b:r)
g _=[]
joeytwiddle
источник
0

Java 7, 100 96 байт

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 & тестовый код:

Попробуй это здесь.

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

Выход: -39

Кевин Круйссен
источник
0

Clojure, 31 байт

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

Кто-то свел задачу уже к одной операции.

Майкл М
источник