文字列の累積勾配を出力します


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
デニスの観察は、このタスクが必要以上に複雑な方法で表現されていることを示しています。
グレッグマーティン

言語は、文字列型をサポートしている場合でも、文字配列として入力を受け入れることができますか?
ポケ

@Pokeすみません、文字列でなければなりません
-dkudriavtsev

@GregMartin私は実際に後でまでそれを実現しませんでした。ただし、課題はこのままです。
dkudriavtsev

@DJMcMayhem知っておくと良いのは、他のすべての形式の出力が許可されていることです。
-dkudriavtsev

回答:


37

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で両方をテストします。


これは結果を印刷しますか?
-dkudriavtsev

4
REPLでは、そうだと思います。ただし、出力の目的の形式は戻り値であり、これはデフォルトの出力方法の1つです。それが許可されていない場合、生産言語の回答のほとんどは無効です。
デニス

21

MATL、2バイト

ds

オンラインでお試しください!

説明:

d連続する文字の差を取得しs、結果の配列を合計します。次に、スタックの一番上の値が暗黙的に印刷されます。それについて他に言うことはあまりありません。

興味深いことに、デニスがすばらしいショートカットを発見したにもかかわらず、それを使用するとMATLで大幅に長くなります。



6

MATLAB、16バイト

@(x)sum(diff(x))

これにより、という名前の匿名関数が作成ansされますans('Hello world!')

ここで、オンラインデモ、追加のバイトを必要とオクターブで+明示的に素子間の差を計算する前に、数値配列に入力文字列を変換するためには、



3

Cubix、13バイト

Cubixは、キューブを包む2次元言語です。

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

LINQを使用したC#、17バイト

hstdeのおかげで、LINQを使用した短いバージョン:

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

Brain-Flak、51バイト

48バイトのコードと-aフラグ用の3バイト。これにより、ASCII入力が可能になります(ただし、10進出力。どのくらい便利です。: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

Brachylog、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

減算は2つの整数の入力に対してのみ機能するため、選択したプレフィックスがの場合は成功し[33, 72]ます。



2

R、69 43 32バイト

Rで可能な解決策を紹介するのは楽しいと思いましたが、非常に競合しない答えです。

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

この回答の唯一の興味深い側面は、の使用であるsapplycharToRaw。最初に、文字列をASCII整数表現に変換する文字のベクトルに分割します。charToRaw関数はRで、代わりに前述のベクトルIの使用中の各値に対するループのベクトル化されていないsapply効果的に機能をベクトル化。その後、最初の差を取り、合計します。


編集:ターンが出て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の観測を使用します。

この場合、些細な解決策が最も短いと思います。

charCodeAt@Neilが示唆する繰り返しを取り除くことで3バイトを節約しました。


私ができることはs=>s.slice(-1).charCodeAt()-s.charCodeAt()、同じ長さであることが判明したことです。
ニール

実際にcharCodeAtは非常に長いので、おそらく繰り返しを避けることでバイトを節約する方法があります。
ニール

@Neil提案をありがとう、3バイト節約できました。
Lmis

少し再帰的なアプローチは、数バイト長くなりますf=s=>(s[1]?-f(s.slice(-1)):0)-s.charCodeAt()
。– ETHproductions

2

4番目、28バイト

: f depth 1- roll swap - . ;

スタック上の文字のリストを取得します(Forthの標準的なパラメータ取得方法)。文字は、スタックの最上部が文字列の最初の文字になるように取得されます。スタックの一番下を一番上に移動し、スワップしてから、減算して印刷します。ガベージはスタックに残り、出力は標準出力に出力されます。

各文字が逆順ではなく順番にスタックにプッシュされると、プログラムは2バイト短くなります。ただし、通常は引数を逆順にプッシュするため、それが許可されているかどうかはわかりません。

オンラインで試す

このように呼び出されます:

33 100 108 114 111 87 32 111 108 108 101 72 f

2

Java、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]途中ですべてのものを相殺するので。


2

PHP 7.1、33 31 bytes

PHP 7.1で実装された負の文字列オフセットを使用します。

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

次のように実行します:

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

微調整

  • を使用して2バイトを保存しました $argn

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 16

1

PHP、36バイト

<?=ord(strrev($s=$argv[1]))-ord($s);
  • 最初と最後を除くすべての文字が追加され、1回ずつ減算されます。
    →差の合計==最初と最後の文字の差
  • ord()PHPでは、文字列の最初の文字で動作します
    →明示的に単一の文字に減らす必要はありません

1

Brain-Flak34 32 + 3 = 35バイト

+ -a3。asciiモードに必要なフラグのため。

オンラインで試す

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

奇妙なことに、最後から最初を引く「トリック」ではなく、仕様で使用されている定義を実際に使用する方が効率的です。

これは、まさにそれを行うことで機能します。

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

1

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

If you use ) instead of W=, you don't need the _. Also, c as a shortcut for 0=.
Dennis

@Dennis Thanks a lot!
Luis Mendo

1

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

I'm afraid this isn't a proper function. It's just a snippet. sum.(tail>>=zipWith(-)).map fromEnum for example is a function.
nimi

@nimi The question didn't ask for a proper function
BlackCap

The question asked for nothing, so the defaults jump in, which are full programs or functions, but not snippets.
nimi

1

Zsh, 22 bytes

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

Try it online!

In arithmetic mode, #name gets the character code of the first character in name. We set c to the last character, and take the difference between the first and last codes.




0

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


0

Clojure, 31 bytes

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

Someone reduced the task already to a single operation.

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.