行方不明の手紙を見つける


27

ガイドライン

仕事

入力として連続する(増加する)文字の配列を受け取り、配列(一部の言語のリスト)にない文字を返すメソッドを記述します。


ルール

  • これはコードゴルフなので、バイト単位の最短回答が勝ちです!
  • 常に有効な配列を取得します
  • 常に1つの文字が欠落している
  • 配列の長さは常に少なくとも2です。
  • 配列には常に1つのケース(大文字または小文字)の文字のみが含まれます。
  • 入力と同じケース(大文字または小文字)で出力する必要があります
  • 配列は常に1文字ずつ移動します(欠落している文字をスキップします)
  • 配列の長さは2〜25です。
  • 配列の最初または最後の要素が失われることはありません

['a','b','c','d','f'] -> 'e'

['O','Q','R','S'] -> 'P'

['x','z'] -> 'y'

['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'] -> 'v'


代わりに文字列を使用できますか?
リーキー修道女

@LeakyNun文字列は文字の配列なので、はい。
アモリス

1
入力用:出力は、(例えば欠けている文字を含む配列にすることができ['a','b','c','d','f','g']、出力['e']?、それはコードの短い行う場合
氏Xcoder

1
Mr.Xcoder A列@文字の配列だけなので、はい
Amorris

2
ルール4は、単にルール8のサブセットであり、削除できます(少なくとも、ルール8の最後に「包括的」という言葉を入れた場合)。
NH。

回答:



11

C#(.NET Core)48 47 46バイト、char配列として入力

s=>{for(int i=0;s[++i]==++s[0];);return s[0];}

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

説明:配列内の最初の要素と、次の要素を繰り返すポインターがインクリメントされます。最初の要素と現在の要素の両方が異なる場合、最初の要素を返します。

C#(.NET Core)58 56 50バイト、文字列として入力

s=>{var c=s[0];while(s.IndexOf(++c)>=0);return c;}

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

以前の58バイトのソリューション(最初のコメントで参照):

s=>{for(int i=1;;i++)if(s[i]-s[0]>i)return(char)(s[i]-1);}

System.Linqを使用したアルゴリズム

次のアルゴリズムはusing System.Linq;、バイト数に(18バイト)を追加する必要があるため、より長くなります。

私はこれをとても気に入っています(52 + 18バイト):

s=>{int i=0;return(char)(s.First(c=>c-s[0]>i++)-1);}

また、1行(45 + 18)バイトのソリューションもあります。

s=>(char)(s.Where((c,i)=>c-s[0]>i).First()-1)

そして、非常に賢い(37 + 18)バイトのソリューション、Ed'kaの厚意による:

s=>s.Select(e=>++e).Except(s).First()

1
すべてのコードパスが値を返すわけではないので、これはコンパイルに失敗しませんか?ただし、との比較チェックでは+1ですs[i]-s[0]
TheLethalCoder

@TheLethalCoder forループには停止条件がないため失敗しません。したがって、if条件がに評価されるまで繰り返し続けますtrue
チャーリー

1
このように8バイトを保存できますa=>{int i=0;for(;a[++i]-a[0]<=i;);return--a[i];}(入力をとして取得する場合char[])。私のおかげではなく、Java 8の回答に対する@Nevayのコメントのおかげです。
ケビンCruijssen

1
@KevinCruijssenは、入力をchar配列として使用して、さらに2バイトを節約する方法を見つけました。
チャーリー

1
より短いLinqバージョン:s=>s.Select(e=>++e).Except(s).First()
Ed'ka

8

アリス、10バイト

/X.
\ior@/

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

説明

これは、順序(文字列処理)モードで完全に動作する線形プログラムの単なるフレームワークです。

/...
\.../

実際の線形コードは次のとおりです。

i.rXo@

どちらが:

i   Read all input.
.   Duplicate.
r   Range expansion. If adjacent letters don't have adjacent code points, the
    intermediate code points are filled in between them. E.g. "ae" would turn
    into "abcde". For the inputs in this challenge, this will simply insert
    the missing letter.
X   Symmetric set difference. Drops all the letters that appear in both strings,
    i.e. everything except the one that was inserted by the range expansion.
o   Output the result.
@   Terminate the program.



7

Java 8、70 57 56 48 46バイト

a->{for(int i=0;++a[0]==a[++i];);return a[0];}

@CarlosAlejoのおかげで、-14(70→56)および-2(48→46)バイト。@Nevayの
おかげで-8(56→48)バイト。

説明:

ここで試してみてください。

a->{            // Method with char-array parameter and char return-type
  for(int i=0;  //  Start index-integer at 0 and loop as long as
    ++a[0]      //   the previous character + 1 (by modifying the character at index 0)
    ==a[++i];   //   equals the next character (by raising the index by 1 before checking)
  );            //  End of loop
  return a[0];  //  Return the now modified character at index 0 in the array
}               // End of method

1
明示的なキャストの代わりに暗黙的なキャストを使用して、8バイトを節約できますa->{int i=0;for(;a[++i]-a[0]<=i;);return--a[i];}
ネヴァイ

6

C(gcc)、3335 36 48 60 バイト

すべての最適化は、32ビットGCCでのみ無効にする必要があります。

f(char*v){v=*v+++1-*v?*v-1:f(v);}

入力を文字列として受け取ります。

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


2
「すべての最適化は、32ビットGCCでのみ無効にする必要があります。」このない作品(のみによるUBに仕事に表示されます)というのが非常に回り道である
sehe

foo(char*a){return*a+1==a[1]?foo(a+1):++*a;}かなりいいと思います。より自然なものより短い1文字のみfoo(char*a){while(*a+1==a[1])a++;return++*a;}
-sehe

@sehe定数未定義の動作はPPCGに許容できると考えられる
Keyuガン

5

Pythonの374の 62 58 44 40バイト

Erik the Outgolferのおかげで-12バイト。Leaky Nunのおかげで-18バイト。musicman523のおかげで-4バイト。

入力をバイト文字列として受け取ります。

lambda s:chr(*{*range(s[0],s[-1])}-{*s})

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

別のクールなソリューション:

lambda s:chr(*{*range(*s[::~-len(s)])}-{*s})

1
.difference({*s})->-{*s}
エリック・ザ・アウトゴルファー




1
あなたの解決策は私が
望ん

4

Mathematica、46バイト

Min@Complement[CharacterRange@@#[[{1,-1}]],#]&

私はそれMin@Complement[CharacterRange@@#[[{1,-1}]],#]&がバイトを節約すると信じています。
LegionMammal978

@ LegionMammal978実際には2!
J42161217

3

JavaScript(ES6)、70バイト

文字配列として入力

(a,p)=>a.some(c=>(q=p+1,p=c.charCodeAt(),p>q))&&String.fromCharCode(q)

少ないゴルフ

a=>{
  p = undefined;
  for(i = 0; c = a[i]; i++)
  {
    q = p+1
    p = c.charCodeAt()
    if (p>q)
      return String.fromCharCode(q)
  }
}

テスト

F=(a,p)=>a.some(c=>(q=p+1,p=c.charCodeAt(),p>q))&&String.fromCharCode(q)

function update() {
  var a0=A0.value.charCodeAt()
  var a1=A1.value.charCodeAt()
  if (a1>a0) {
    var r = [...Array(a1-a0+1)]
      .map((x,i)=>String.fromCharCode(a0+i))
      .filter(x => x != AX.value)
    I.textContent = r.join('') + " => " + F(r)
  }
  else {
    I.textContent=''
  }
}

update()
input { width: 1em }
Range from <input id=A0 value='O' pattern='[a-zA-Z]' length=1 oninput='update()'>
to <input id=A1 value='T' pattern='[a-zA-Z]' length=1 oninput='update()'>
excluding <input id=AX value='Q' pattern='[a-zA-Z]' length=1 oninput='update()'>
<pre id=I></pre>



3

網膜33 25バイト

$
¶$_
T`p`_p`.*$
D`.
!`.$

オンラインでお試しください!任意の範囲のASCII文字で動作します。編集:@MartinEnderのおかげで8バイトを保存しました。説明:最初のステージは入力を複製します。2番目は、コピー内のすべての文字を1コードポイント減らします。3番目の段階では、コピーに含まれる文字のうち、オリジナルに残っているものがすべて削除されます。これにより、元の入力、元の入力の最初の文字の前の文字、および欠落している文字がそのまま残ります。最後の段階では、不足しているキャラクターと一致します。


ここでは、同じ基本的な考え方を使用して、25である:tio.run/##K0otycxL/P9fhevQNpV4rpCEgoT4ggQ9LRUulwQ9LsUEPZX///...(それはバイトを節約するので、私は二行目をデクリメントだし、それから、私は重複排除機能を使用して独自の文字を見つけています。)
マーティンエンダー

@MartinEnder重複排除は、私はすべてに沿って欲しかった、まさにであり、私はすでに網膜がそれを持って忘れてしまった、ため息...(私が知っている最初の行をインクリメントすると、複数の第二ラインをデクリメントよりもバイトを取りますが、それは試合が短くregexで作られた。)
ニール

3

SWIプロローグ、124バイト

m([H|T]):-n(H,N),c(T,N),!,m(T).
n(I,N):-o(I,C),D is C+1,o(N,D).
c([N|_],N).
c(_,N):-print(N),!,fail.
o(C,O):-char_code(C,O).

例:

?- m(['a','b','c','d','f']).
e
false.

?- m(['O','Q','R','S']).
'P'
false.

?- m(['x','z']).
y
false.

?- m(['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z']).
v
false.

少し説明:

これmは「メイン」プロシージャでありn、リスト内で次に期待される文字を生成します。c比較を行う-期待が次の項目に一致した場合、他の予想される文字をプリントアウトし、窓の外にジャンプし続けます。


1
より短いfail0=1
マット

3

C ++ 14、標準ライブラリ、汎用コンテナタイプ(87 86バイト)

[](auto a){return++*adjacent_find(begin(a),end(a),[](auto a,auto b){return a+1!=b;});}

名前空間からコンテナタイプは::std例えば(仮定されstd::stringstd::listまたはstd::vectorそれ以外の場合using namespace std;または同様と仮定されるだろう。

@Venのおかげで、プリプロセッサを少しハッキングすることで、82バイト(1改行)まで削減できます。

#define x [](auto a,int b=0){return++
x *adjacent_find(begin(a),end(a),x a!=b;});}

それを見て Live On Coliru

C ++ 14標準ライブラリなし(まだ汎用、64 63バイト)

[](auto& a){auto p=*begin(a);for(auto c:a)if(c!=p++)return--p;}

繰り返しますが、名前空間からではない::std(または関連付けられている)コンテナタイプの場合にのみ、名前の検索を支援する必要があります

Live On Colirustd::stringなど

Live On Coliruchar const[]など


取り消し線のテキストと次のテキストの間にスペースを入れる必要があります。
CJデニス

@CJDennis完了。ちなみに、現在の担当者(2469)は美しい数字です(3 * 823で、視覚的に(24)(69)としてペアリングされている(2 2 2 3)(3 23))
sehe


2

C#、104バイト

using System.Linq;a=>(char)Enumerable.Range(a.Min(),a.Max()-a.Min()).Except(a.Select(c=>(int)c)).First()

フル/フォーマット済みバージョン:

using System.Linq;

namespace System
{
    class P
    {
        static void Main()
        {
            Func<char[], char> f = a =>
                (char)Enumerable.Range(a.Min(), a.Max() - a.Min())
                                .Except(a.Select(c=>(int)c))
                                .First();

            Console.WriteLine(f(new[] { 'a', 'b', 'c', 'd', 'f' }));

            Console.ReadLine();
        }
    }
}

Ed'kaによる非常に賢いLinqバージョンs=>s.Select(e=>++e).Except(s).First()
チャーリー

@CarlosAlejoあなたが答えにそれを追加したのを見たので、私は私のものを更新しませんが、はい、それは非常に賢いです。私のバージョンよりもずっと短いです。
TheLethalCoder

2

MATL、8 7バイト

@Luisのおかげで1バイト節約

tdqf)Qc

MATL Online試しください

説明

      % Implicitly grab the input as a string
t     % Duplicate the string
d     % Compute the differences between successive characters
q     % Subtract 1 from each element
f     % Get the locations of all non-zero characters (1-based index)
)     % Extract that character from the string
Q     % Add one to get the next character (the missing one)
c     % Convert to character and display

@LuisMendo素晴らしい、ありがとう!
Suever

2

Excel、110 + 2 = 112バイト

=CHAR(CODE(LEFT(A1))-1+MATCH(0,IFERROR(FIND(CHAR(ROW(INDIRECT(CODE(LEFT(A1))&":"&CODE(RIGHT(A1))))),A1),0),0))

両端に中括弧を追加し、2バイトを追加する配列式(Ctrl+ Shift+ Enter)として入力する必要があり{ }ます。入力は文字列としてで、OPごとにA1 OKです。

これは、これまでのところ最も短い回答ではありませんが(Excelはめったにありません)、それができるかどうかを見るのが好きです。



2

CJam、6バイト(フルプログラム)/ 7バイト(コードブロック)

q),^W=

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

これは、標準入力から入力文字列を読み取り、不足している文字を標準出力に出力する完全なCJamプログラムです。CJamには実際には「メソッド」がありません。これはチャレンジが求めているものですが、最も近いものはおそらく次のような実行可能コードブロックでしょう。

{),^W=}

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

このコードブロックは、評価されると、入力をスタック上の文字列(つまり、文字の配列)として受け取り、スタック上にも見つからない文字を返します。


説明:完全なプログラムでq、入力ストリングを読み取り、スタックに配置します。 )次に、入力文字列の最後の文字からポップし、範囲演算子,は、その下にコードポイントを持つすべての文字(アルファベットの前のすべての文字を含む)を含む配列に変換します。したがって、例えば、入力された場合はcdfgh、その後、後に),スタックは、文字列が含まれますcdfg(つまり、最後の文字で入力が削除)と...abcdefg場所、...以下のASCIIコードを持つ文字の束の略でa取り外した最後の入力以下(すなわち、すべての文字文字)。

次に、対称集合差分演算子^は、これらの文字列を結合して、両方ではなく文字列のいずれかに表示される文字を正確に含む単一の文字列にします。文字列に文字が現れる順序を保持するため、入力例のcdfg場合、結果はに),^なります...abe。ここ...でも、以下のASCIIコードの文字の束を表しますa。最後に、W=この文字列の最後の文字を抽出します。これは、e検索したかった欠落文字だけです(残りは破棄します)。プログラムが終了すると、CJamインタープリターはスタックの内容を暗黙的に出力します。


ボーナス:GolfScript、6バイト(フルプログラム)

),^-1>

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

GolfScriptでもほぼ同じコードが機能することがわかりました。GolfScriptの暗黙的な入力のため、完全なプログラムバージョンでは1バイトを節約しますが、CJamとは異なりW、GolfScriptには-1に初期化された便利な1文字の変数がないため、1バイトを失います。

また、CJamには整数型と文字型があります(文字列は文字を含む単なる配列です)が、GolfScriptには整数型が1つしかありません(そして、通常の配列とは多少異なる動作をする特別な文字列型があります)。このすべての結果、GolfScriptインタープリターにASCIIコード番号の代わりに実際に欠落している文字を出力させたい場合、文字そのものではなく単一文字の文字列を返す必要があります。幸いなことに、ここでその変更を行うには、インデックス演算子=を配列/文字列の左側の切り捨て演算子に置き換えるだけ>です。

もちろん、GolfScriptの暗黙的なI / Oのおかげで、上記のコードは、スタックから文字列を読み取り、不足している文字を含む1文字の文字列を返すスニペットとしても使用できます。または、むしろ、スタック上の単一の文字列を引数として受け取り、その出力をスタック上の印刷可能な文字列として返すスニペットも、完全なGolfScriptプログラムです。


6
コードスニペットはデフォルトでは許可されいません。機能と完全なプログラムのみです。したがって、おそらくq(プログラム)または{...}(ブロック)が必要です。ただし、アプローチのために+1
ルイスメンドー

これは非常に賢いです!
エソランジングフルーツ

2

、6バイト

→S-(ḣ→

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

この関数は、入力として文字列(文字のリスト)を受け取り、出力として文字を返します。

説明

→S-(ḣ→
    ḣ→    Get the list of all characters from the null byte to the last character of the input
 S-       Subtract the input from this list
→         Get the last element of the result

2

Python 2-76バイト

既存のpython 2ソリューションは失われますが、少し異なるアプローチなので、とにかく投稿したいと思いました。

lambda c:[chr(x)for x in range(ord(c[0]),ord(c[0]+26)if chr(x)not in c][0]

2

8番目、99バイト

根拠

文字間の距離が2より大きい場合、文字が欠落しています。文字の距離は、各文字のASCIIコードの差を計算することによって取得されます。

コード

: f ' nip s:each repeat over n:- 2 n:= if n:1+ "" swap s:+ . reset 1 then depth n:1- while! reset ;

ゴルフされていないバージョン

: f \ s -- c 
  ' nip s:each    \ convert each letter into its ASCII code and put them on stack
  repeat
    over
    n:- 2 n:=     \ check if there is a missing letter 
    if            
      n:1+        \ compute the ASCII code of missing letter
      "" swap s:+ \ convert ASCII code into printable character
      .           \ print out the missing letter
      reset 1     \ set condition to exit from while!
    then
    depth n:1-    \ verify if there are letters to check
  while!          
  reset           \ clean stack
;

使用法と例

ok> "abcdf" f
e
ok> "OQRS" f
P
ok> "xz" f
y
ok> "abcdefghijklmnopqrstuwxyz" f
v
ok> "ab" f

ok> "def" f

ok>

2

JavaScript(ES6)、64バイト

入力を文字列として受け取ります。

s=>(g=p=>(c=String.fromCharCode(n++))<s[p]?p?c:g(p):g(p+1))(n=0)

どうやって?

  • 初期化:で始まる n = 0および p = 0から、再帰関数 g()を呼び出します。

    g = p =>                                   // given p
      (c = String.fromCharCode(n++)) < s[p] ?  // if the next char. c is not equal to s[p]:
        p ?                                    //   if p is not equal to zero:
          c                                    //     step #3
        :                                      //   else:
          g(p)                                 //     step #1
      :                                        // else:
        g(p + 1)                               //   step #2
  • ステップ#1:入力文字列s [0]の最初の文字に等しくなるまでnをインクリメントします。c = String.fromCharCode(n)

  • ステップ#2:同期が完了したので、両方をインクリメントします 完了したc = String.fromCharCode(n)ので、 s [p]と等しくなくなるまで n pを同時に。

  • ステップ#3:cを返します:見つからなかった期待される文字。

テストケース


1

J、20バイト

{&a.>:I.1 0 1&E.a.e.
  • a.e. ASCII文字セット全体の入力文字のブールマスク
  • 1 0 1&E. シーケンスが 101がそのインデックスで始まる、つまり「スキップ」シーケンスが始まる場所を見つける
  • I. そのマッチのインデックス、すなわちスキップされたものの前の文字
  • >: 1ずつインクリメントします。つまり、ascii文字セット内のスキップされた文字のインデックス
  • {&a. ASCII文字セットからそのインデックスを選択します。つまり、スキップされた文字を返します

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


それは私にはスニペットのように見えます。
アダム

@Adámこれは暗黙の(ポイントフリー)スタイルで書かれており、スニペットではなく「関数のようなもの」と見なされます。私の知る限り、それはあなたのAPLソリューションほどスニペットではありません(しかし、dyalogがわからないので、一言で言ってください)。
zgrep

@Adámはい、変数に割り当てることはできませんが、その右側で入力を想定しているという意味でそうです。これは違法ですか?私はどこかでそれについて尋ね、それは大丈夫だったと言われました
ジョナ

APL / J / Kについての私の理解は、割り当てによって、または本体として明示的な動詞/関数として(名前は明示的なフォームにも明示的に入力する必要があります)、コードは名前に常駐できる必要があるということです。スニペットは、変数内の値を前提とするコードであり、および/または行に貼り付ける必要がありますが、単独で立つことはできません。
アダム

@zgrepいいえ、このコードは明示的(暗黙的ではありません)ですが、右端の引数への参照が欠落しています。私のAPL関数は、括弧を割り当てたり挿入したりできる完全な暗黙の関数です。
アダム

1

ES6、125バイト:

(a=>((s,f)=>(r=(i,b)=>a[i]?r(i+1,b||(s[f](i)-s[f](i-1)-1&&String.fromCharCode(s[f](i-1)+1))):b)(1,0))(a.join(""),"charCodeAt"))

http://jsbin.com/vasoqidawe/edit?console

返された関数は配列で呼び出す必要があります

(["a","c"])

.join( "")を削除して文字列を渡すことで、さらに9バイト節約できます。

("ac")

ES6、108バイト:

(a=>((s,f,o)=>(a.find((_,i)=>(o?++o:o=s[f](i))!==s[f](i)),String.fromCharCode(o)))(a.join(""),'charCodeAt'),0))

http://jsbin.com/tudiribiye/edit?console


1
バインド??? コードゴルフで?
edc65

@ edc65どうしたの?(これがn00bの場合は申し訳ありませんが、それは私の最初のゴルフです:))
ジョナスウィルムズ

@ edc65しかし、youreのはおそらく正しい、それを削除すると、4バイト...保存
ジョナスウィルムス

a.join("")可能性がありますa.join``
user2428118


1

Python 2、69バイト

lambda a:chr((ord(a[0])+ord(a[-1]))*-~len(a)/2-sum(ord(x)for x in a))

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

いくつかの説明リストの最初と最後の要素を知っているので、list + the missed char算術級数の要約式を使用して)のすべての文字のコードの合計を簡単に計算できます。この合計と内のすべての文字のコードの合計との差が、逃した文字のコードになります。 list


1

205AB1Eをほとんど知らないにもかかわらず、同じアルゴリズムを使用していることから判断します:)
リーキー

@LeakyNunまあ、私もアルゴリズムを考えました...
エリックアウトゴルファー

アルゴリズムを変更しました。
リーキー修道女

@LeakyNunとにかく05AB1Eのほうが長くなります。
エリックアウトゴルファー

私だけの考え2を含む別のアルゴリズム ...あなたかもしれない、
漏れ修道女

1

APL(Dyalog)、17バイト

(⊃⎕AV/⍨∨\∧~)⎕AV∘∊

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

⎕AV∘∊ ブール値:A tomic Vの各文字引数(文字セット)メンバーの?

()  次の暗黙関数を適用します。

 の最初の要素

⎕AVAトミックVエクター(文字セット)

/⍨ どれ

∨\ 初期値の後に(引数のメンバー)

 しかし

~ ではない(引数のメンバー)

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