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


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.

правила

  • Применяются стандартные лазейки
  • Не используйте готовые функции, которые выполняют эту задачу
  • Творческие решения поощряются
  • Веселиться
  • Это помечено как , самый короткий ответ в байтах выигрывает, но не будет выбран.

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



3

Cubix , 13 байт

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

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

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

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

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

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

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

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

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;

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!"]

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


Вам не нужно печатать вывод, только вернуть его, чтобы вы могли избавиться от $><<.
— Джордан

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

Брахилог , 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].



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())))

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}

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


Извините, но вы не можете предположить, 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.


Лучшее, что я мог сделать, это то, 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

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]что все содержимое в середине сокращается.



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 неявно обращается к аргументам из стека и возвращает их таким же образом. Любые строковые данные, оставленные в стеке после завершения программы, печатаются неявно.


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

1

PHP, 36 байт

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

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последний символ и берем разницу между первым и последним кодами.




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 %)))

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.