Виведіть сукупний нахил рядка


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 я насправді цього не усвідомлював до пізніше. Але виклик повинен залишатися таким.
dkudriavtsev

@DJMcMayhem Приємно знати, що всі інші форми вихідних даних дозволені.
dkudriavtsev

Відповіді:


38

Пітон, 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 .


Це друкує результат?
dkudriavtsev

4
Я думаю, що це відповідає. Передбачувана форма виводу - це повернене значення, яке є одним із наших методів виводу за замовчуванням. Якщо це не дозволено, більшість відповідей на мовах виробництва є недійсними.
Денніс

22

MATL , 2 байти

ds

Спробуйте в Інтернеті!

Пояснення:

dотримує різницю між послідовними символами та sпідсумовує отриманий масив. Потім значення над стеком неявно друкується. Не багато про що сказати про це.

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



6

MATLAB, 16 байт

@(x)sum(diff(x))

Це створює анонімну функцію з ім'ям , ansяке можна назвати як: ans('Hello world!').

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



3

Кубікс , 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}

Призначте до змінної на кшталт f=->s{s[-1].ord-s[0].ord}і схожої на викликf["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

Мозок-Флак , 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 байт

Дуже не конкуруюча відповідь, хоча я думав, що було б цікаво продемонструвати можливе рішення у Р.

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 байти.
Лміс

Трохи рекурсивний підхід на кілька байт довший:f=s=>(s[1]?-f(s.slice(-1)):0)-s.charCodeAt()
ETHproductions

2

По-четверте, 28 байт

: f depth 1- roll swap - . ;

Складає список символів на стеку (стандартний метод Форта збору параметрів.) Символи приймаються таким чином, що верхня частина стека є першим символом рядка. Я переміщую нижню частину стека вгору, поміняю місцями, потім віднімаю і друкую. Сміття залишається на стеку, а вихід друкується до stdout.

Якби кожен символ був висунутий у стек в порядку замість зворотного порядку, програма була б на 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];}

Безголівки:

  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☼[+і це трохи приємно.
Атако

1

PHP, 36 байт

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

1

Мозг-Флак , 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;}

Невикористаний і тестовий код:

Спробуйте тут.

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.